Beispiel #1
0
def edit_paper_url(url):

    from vimbox.remote.paper_backend import StorageBackEnd, DOC_REGEX
    title, did, doc_id = DOC_REGEX.match(url).groups()
    paper_token = local.load_config()['DROPBOX_TOKEN']
    client = StorageBackEnd(paper_token)
    response = client.file_download(url)
    local_folder = local.get_local_file('.paper/')
    if not os.path.isdir(local_folder):
        os.mkdir(local_folder)
    local_file = "%s/%s--%s-%s.md" % (local_folder, title, did, doc_id)
    content = local.local_edit(local_file, response['content'])
    # Update remote if there are changes
    if content != response['content']:
        response = client.files_upload(content, url, response['revision'])
        if response['status'] == 'api-error':
            print(response['alert'])
    os.remove(local_file)
Beispiel #2
0
def reset_folder(folder_path, delete=False):

    # Local
    local_unit_test_folder = local.get_local_file(REMOTE_UNIT_TEST_FOLDER)
    unit_test_name = os.path.basename(local_unit_test_folder[:-1])
    assert unit_test_name == '.vimbox_unit_test', \
        "unit-test folder changed name. Aborting just in case."

    # Remote
    # NOTE: This assumes these operations pass the unit test!
    client = VimboxClient()
    ret = client.client.file_type(REMOTE_UNIT_TEST_FOLDER[:-1])
    if ret['status'] == 'online' and ret['content'] == 'dir':
        client.client.files_delete(REMOTE_UNIT_TEST_FOLDER[:-1])
        print("Removed %s" % REMOTE_UNIT_TEST_FOLDER)
    if os.path.isdir(local_unit_test_folder):
        shutil.rmtree(local_unit_test_folder)
    if not delete:
        client.client.make_directory(REMOTE_UNIT_TEST_FOLDER[:-1])
        os.mkdir(local_unit_test_folder)
Beispiel #3
0
def test_main(backend_name):

    # Creation
    tmp_file = '%sfolder1/plain' % REMOTE_UNIT_TEST_FOLDER
    assert main(['-f', tmp_file, 'This is some text'])
    # Check a local copy was created (if intended)
    assert os.path.isfile(get_local_file(tmp_file)), \
        "Creation of local file %s failed" % tmp_file

    tmp_file = '%sfolder1/encrypted' % REMOTE_UNIT_TEST_FOLDER
    worked = main(
        ['-e', tmp_file, 'This is some encrypted text'], password='******'
    )
    assert not worked, "Should not be able to create encrypted file offline"
    assert not main(['rm', tmp_file]), \
        "Should not be able to remove files offline"
    assert not main(['cp', tmp_file, tmp_file + '2']), \
        "Should not be able to copy files offline"
    tmp_folder = '%sfolder1/folder2/' % REMOTE_UNIT_TEST_FOLDER
    assert not main(['mkdir', tmp_folder]), \
        "Should not be able to make folder offline"
Beispiel #4
0
    def make_directory(self, remote_target):
        if remote_target[-1] != '/':
            raise VimboxClientError("Folder paths must end in / ")
        file_type, is_encripted, status = self.file_type(remote_target)
        if status != 'online':
            raise VimboxOfflineError("Connection error")

        if file_type is None:
            response = self.client.make_directory(remote_target[:-1])
            if response['status'] == 'online':
                # Local file
                os.mkdir(local.get_local_file(remote_target))
                # Cache
                self.register_file(remote_target, False)
        elif file_type == 'dir':
            raise VimboxClientError("%s already exists" % remote_target)
        elif is_encripted:
            raise VimboxClientError("%s already exists as an encrypted file" %
                                    remote_target)
        else:
            raise VimboxClientError("%s already exists as a file" %
                                    remote_target)

        return {'status': status, 'content': None, 'alert': None}
Beispiel #5
0
    def list_folders(self, remote_folder):
        """ list folder content in remote """

        # Try first remote
        if remote_folder and remote_folder[-1] == '/':
            response = self.client.list_folders(remote_folder[:-1])
        else:
            response = self.client.list_folders(remote_folder)
        entries = response['content']['entries']
        is_files = response['content']['is_files']
        status = response['status']
        message = response['alerts']

        # Second try to see if there is an ecrypted file
        # TODO: entries is None is used to signal a this is a file not a
        # folder. This is an obscure way of dealing with this.
        is_encrypted = False
        if status == 'online' and entries is False:
            enc_remote_folder = crypto.get_path_hash(remote_folder)
            response = self.client.list_folders(enc_remote_folder)
            entries = response['content']['entries']
            is_files = response['content']['is_files']
            status = response['status']
            message = response['alerts']
            is_encrypted = status == 'online'

        display_string = ""
        if status == 'api-error':
            raise VimboxClientError("api-error")

        elif status == 'online' and entries is False:
            # Folder/File non existing
            raise VimboxClientError("%s does not exist in remote" %
                                    remote_folder)

        elif status == 'online' and entries is None:
            # This was a file
            return True

        elif status == 'online':

            # Differentiate file and folders
            display_folders = []
            for entry, is_file in zip(entries, is_files):
                # Add slash to files on root
                if remote_folder == '':
                    entry = '/' + entry
                if is_file:
                    # File
                    display_folders.append(entry)
                else:
                    # Folder
                    display_folders.append("%s/" % entry)
            display_folders = sorted(display_folders)

            # Update to match folder
            if remote_folder:

                # Remove folder paths no more in remote
                for path in self.config['cache']:
                    if path[:len(remote_folder)] == remote_folder:
                        cache_folder = \
                            path[len(remote_folder):].split('/')[0] + '/'
                        if (cache_folder not in display_folders
                                and cache_folder != ''):
                            self.config['cache'].remove(path)

                # Add missing folders
                if remote_folder not in self.config['cache']:
                    self.config['cache'].append(remote_folder)
                for folder in display_folders:
                    if folder[-1] == '/':
                        new_path = "%s%s" % (remote_folder, folder)
                        if new_path not in self.config['cache']:
                            self.config['cache'].append(new_path)

                # Write cache
                self.config['cache'] = sorted(self.config['cache'])
                local.write_config(self.config_path, self.config)

            # Replace encrypted files
            entry_types = []
            new_display_folders = []
            for entry in display_folders:
                key = "%s%s" % (remote_folder, entry)
                if key in self.config['path_hashes'].keys():
                    entry_types.append('encrypted')
                    new_display_folders.append(
                        os.path.basename(self.config['path_hashes'][key]))
                elif entry[-1] == '/':
                    entry_types.append('folder')
                    new_display_folders.append(entry)
                else:
                    entry_types.append(None)
                    new_display_folders.append(entry)
            display_folders = new_display_folders

            # Display entries sorted and with colors
            new_display_folders = []
            indices = sorted(range(len(display_folders)),
                             key=display_folders.__getitem__)
            for file_folder, entry_type in zip(display_folders, entry_types):
                if entry_type == 'encrypted':
                    file_folder = red(file_folder)
                elif entry_type == 'folder':
                    file_folder = blue(file_folder)
                new_display_folders.append(file_folder)
            display_string = "".join(
                ["%s\n" % new_display_folders[index] for index in indices])

            # Add file to cache
            if remote_folder not in self.config['cache']:
                self.config['cache'].append(remote_folder)
                local.write_config(self.config_path, self.config)

        elif os.path.isdir(local.get_local_file(remote_folder)):

            # If it fails resort to local cache
            display_folders = local.list_local(remote_folder, self.config)
            if self.verbose > 0:
                print("\n%s content for %s " % (red("offline"), remote_folder))
            display_string = "".join(
                ["%s\n" % folder for folder in sorted(display_folders)])

        # Print
        if self.verbose > 0:
            print("\n%s\n" % display_string.rstrip())
Beispiel #6
0
 def get_local_file(self, remote_file):
     return local.get_local_file(remote_file, self.config)
Beispiel #7
0
def is_local_dir(file_path):
    local_file = local.get_local_file(file_path)
    return os.path.isdir(local_file)
Beispiel #8
0
def main(args=None, config_path=None, password=None, verbose=1):
    """
    This is refered as vimbox in setup.py
    """

    # Argument handling
    if config_path is None:
        config_path = local.CONFIG_FILE
    if args is None:
        # From command line
        args = sys.argv[1:]
    if len(args) == 0:
        vimbox_help()
        return False
    # Sanity check: back-end is installed
    if (args[0] not in ['setup', 'complete']
            and not os.path.isfile(local.CONFIG_FILE)):
        print("\nMissing config in %s\nRun vimbox setup\n" % local.CONFIG_FILE)
        exit(1)

    #
    # LOCAL COMMANDS (will work offline)
    #

    if args[0] == 'help':

        # help
        if len(args) > 1 and args[1] in COMMAND_ORDER:
            vimbox_help(args[1])
        else:
            vimbox_help()
        return True

    elif args[0] == 'complete':

        # strings to store when calling command -W in .basrc
        for autocomplete_option in local.get_complete_arguments():
            print(autocomplete_option)
        return True

    elif args[0] == 'local':

        if len(args) == 2:
            print(local.get_local_file(args[1]))
            return True
        else:
            vimbox_help()
            return False

    elif args[0] == 'cache':

        # Folders cached in this computer (latter minus commans e.g. ls)
        for cached_file in sorted(local.get_cache()):
            print(cached_file)
        return True

    elif args[0] == 'local':

        if len(args) == 2:
            alert = assert_valid_path(args[1])
            if alert:
                print("%s" % alert)
                return False
            print(local.get_local_file(args[1]))
        else:
            vimbox_help()
            return False

    elif args[0] == 'config':

        # Open config in editor
        local.edit_config()
        return True

    elif args[0] == 'setup':

        # Set-up back-end
        try:
            install()
            return True

        except VimboxOfflineError:
            print("\nCan not install vimbox offline! (keep the token)")
            return False

    #
    # REMOTE COMMANDS (some may have offline functionalities)
    #

    elif args[0] == 'ls':

        # List contents of folder

        # Argument handling
        if len(args) == 1:
            argument = ''
        elif len(args) == 2:
            argument = args[1]
            alert = assert_valid_path(argument)
            if alert:
                print("%s" % alert)
                return False
        else:
            vimbox_help()
            return False

        # Client
        client = VimboxClient(config_path=config_path, verbose=verbose)
        try:
            client.list_folders(argument)
            return True

        except KeyboardInterrupt:

            print("\nOperation canceled by user")
            return False

        except VimboxClientError as exception:
            print("%s" % str(exception))
            return False

    elif args[0] == 'mkdir':

        # Copy file to file or folder
        client = VimboxClient(config_path=config_path, verbose=verbose)
        if len(args) != 2:
            vimbox_help()
            return False
        try:
            alert = assert_valid_path(args[1], path_type='dir')
            if alert:
                print("%s" % alert)
                return False
            client.make_directory(args[1])
            return True
        except KeyboardInterrupt:
            print("\nOperation canceled by user")
            return False
        except VimboxOfflineError:
            print("\nCan not create folders offline")
            return False
        except VimboxClientError as exception:
            print("\n%s" % str(exception))
            return False

    elif args[0] == 'cp':

        # Argument handling
        if len(args) != 3:
            vimbox_help()
            return False

        # Copy file to file or folder
        client = VimboxClient(config_path=config_path, verbose=verbose)
        try:
            alert = assert_valid_path(args[1])
            if alert:
                print("%s" % alert)
                return False
            alert = assert_valid_path(args[2])
            if alert:
                print("%s" % alert)
                return False
            client.copy(args[1], args[2])
            return True
        except KeyboardInterrupt:
            print("\nOperation canceled by user")
            return False
        except VimboxOfflineError:
            print("\nCan not copy files offline")
            return False
        except VimboxClientError as exception:
            print("\n%s" % str(exception))
            return False

    elif args[0] == 'cat':

        # Copy file to file or folder
        client = VimboxClient(config_path=config_path, verbose=verbose)
        for arg in args[1:]:
            try:
                alert = assert_valid_path(arg, path_type='file')
                if alert:
                    print("%s" % alert)
                    return False
                client.cat(arg)
                return True
            except KeyboardInterrupt:
                print("\nOperation canceled by user")
                return False
            except VimboxClientError as exception:
                print("\n%s" % str(exception))
                return False

    elif args[0] == 'rm':

        # Remove file or folder

        # argument processing
        if len(args) == 2:
            arguments = args[1]
            recursive_flag = False
        elif len(args) == 3 and args[1] == '-R':
            arguments = args[2]
            recursive_flag = True
        else:
            vimbox_help()
            return False

        # Call client
        client = VimboxClient(config_path=config_path, verbose=verbose)
        try:
            alert = assert_valid_path(arguments)
            if alert:
                print("%s" % alert)
                return False
            client.remove(arguments, recursive=recursive_flag)
            return True
        except KeyboardInterrupt:
            print("\nOperation canceled by user")
            return False
        except VimboxOfflineError:
            print("\nCan not remove files offline")
            return False
        except VimboxClientError as exception:
            print("%s" % str(exception))
            return False

    elif args[0] == 'mv':

        # Move file to file or folder

        # Argument handling
        if len(args) != 3:
            vimbox_help()
            return False

        # Call client
        client = VimboxClient(config_path=config_path, verbose=verbose)
        try:
            alert = assert_valid_path(args[1])
            if alert:
                print("%s" % alert)
                return False
            alert = assert_valid_path(args[2])
            if alert:
                print("%s" % alert)
                return False
            client.move(args[1], args[2])
            return True
        except KeyboardInterrupt:
            print("\nOperation canceled by user")
            return False
        except VimboxOfflineError:
            print("\nCan not move files offline")
            return False
        except VimboxClientError as exception:
            print("%s" % str(exception))
            return False

    else:

        # Get flags from arguments
        arguments = argument_handling(args)
        if not arguments:
            vimbox_help()
            return False
        remote_file, force_creation, encrypt, initial_text = arguments
        alert = assert_valid_path(remote_file)
        if alert:
            print("%s" % alert)
            return False

        # Edit
        if DOC_REGEX.match(remote_file):

            # Edit URL
            from vimbox.remote.primitives import edit_paper_url
            edit_paper_url(remote_file)

        elif remote_file[-1] == '/':

            # Alias for ls
            client = VimboxClient(config_path=config_path, verbose=verbose)
            client.list_folders(remote_file)
            return True

        else:

            # Edit file
            client = VimboxClient(config_path=config_path, verbose=verbose)

            # Create new encrypted file or register existing one
            # TODO: This should happend inside of the client
            if encrypt and password is None:
                try:
                    password = password_prompt(remote_file, client.config)
                except KeyboardInterrupt:
                    print("\nOperation canceled by user")
                    return False
                except VimboxClientError as exception:
                    print("%s" % str(exception))
                    return False

            # Call function
            try:
                client.edit(remote_file,
                            force_creation=force_creation,
                            password=password,
                            initial_text=initial_text)
                return True

            except KeyboardInterrupt:

                print("\nOperation canceled by user")
                return False

            except VimboxOfflineError:

                # Offline mode
                local_file = local.get_local_file(remote_file)
                if password:
                    print("\nCan not create encrypted files offline")
                    return False
                else:
                    # Extra edit mode offline
                    offline_edit(local_file, initial_text)
                    return True

            except VimboxClientError as exception:
                print("%s" % str(exception))
                return False