def is_file_and_exists(candidate: str):
    """Check that the given candidate is valid

    It is invalid if:

    * It is empty
    * It does not point to anything existing in the file system
    * It does not point to a file

    Args:
        candidate (str): the file-path candidate

    Returns:
        if valid:
          candidate, False
        if not:
           candidate, indication

    """
    if candidate == '':
        return candidate, (
            f'The Path to the file to sync should not be empty.')

    if not sanitize_path(candidate).exists():
        return candidate, (f'The path {candidate} does not exist.')

    # is_file_and_exists points to a file
    if not sanitize_path(candidate).is_file():
        return candidate, (f'The path {candidate} does not point to a file.')

    return candidate, False
def load(version: str='')->tuple:
    """Load, validate and process the config for the specified version

    The processing consists of:

    * Setting the path for the google-api SSO token for the google_services
      package (https://github.com/Retzoh/google_services_wrapper)
    * Return the config elements, ready to be fed to the other scripts (e.g.
      sync, ...)

    Args:
        version(str): version of the configuration to use

    Returns:
        (local_file_path: pathlib.Path, cloud_file_id: str,
        cache_folder: pathlib.Path)
    """
    if version == '':
        version = 'default'

    config = validate_config(_read(version), context_msg=(
            f' Please make sure that you have followed the '
            f'instructions at '
            f'https://github.com/Retzoh/keypass_google_drive_sync to download'
            f'a google-SSO token and run `python -m keypass-sync init`. '
            f'Config version: {version}.'))

    if 'credential_folder_path' in config.keys():
        logger.info('setting credential path')
        services_config.default.credential_path = config[
            'credential_folder_path']

    return (sanitize_path(config['local_file_path']),
            config['cloud_file_id'],
            sanitize_path(config['cache_folder']))
def init(version: str='')->None:
    """Setup everything to be able to sync a file

    The setup steps are:

    * Ask the user for the config elements
    * Copy the OAuth 2 Id file to the inter-data folder (
      ~/.keypass_google_drive_sync/)
    * Validate the config elements
    * Save the config

    Args:
        version (str): version of the configuration to use
    """

    if version == '':
        version = 'default'
    config = _read(version)

    print('Setting up the configuration for the syncing utility with '
          'google-cloud.')
    _ = input('Make sure that your have followed the instructions about:\n'
              '- how to download your google-SSO token\n'
              '- getting the id of the keypass database on the cloud\n'
              'at https://github.com/Retzoh/keypass_google_drive_sync.\n'
              '[Ok]')

    root_path = create_folder_if_needed(
        sanitize_path(default_config_path) / f'{version}_SSO')

    (root_path / 'client_id.json')\
        .write_text(
        sanitize_path(
            ask_user.credential_file_path(
                root_path, config['credential_folder_path'] + '/client_id.json')
        ).read_text())
    config['credential_folder_path'] = str(root_path)

    # Getting local_file_path
    config["local_file_path"] = ask_user.local_file_path(
        config['local_file_path'])

    config["cloud_file_id"] = ask_user.cloud_file_id(config['cloud_file_id'])

    _write(validate.config(config, version), version)
def credential_folder_path(candidate: str):
    """Check that given credential_folder_path candidate is valid

    Credential_folder_path contains at least `client_id.json` or `token.json`

    Args:
        candidate (str): the credential path candidate

    Returns:
        if valid:
          candidate, False
        if not:
           candidate, indication
    """
    candidate = sanitize_path(candidate)
    if not (candidate / 'token.json').exists() \
            and not (candidate / 'client_id.json').exists():
        return candidate, (
            f'No credential data (token.json of client_id.json) were found at'
            f'{candidate}.')

    return candidate, False
def get_config_file_path(version):
    return sanitize_path(default_config_path) / version