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 _write(config: dict, version: str= 'default')->dict:
    """Save a config

    The config should contain:

    * A `credential_folder_path` entry pointing to an existing folder
      containing at least a `client_id.json` or `token.json` file. The
      validity of those files will be checked later by the google_services
      package (https://github.com/Retzoh/google_services_wrapper).
    * A `local_file_path` telling where the file to sync is, on the local
      machine
    * A `cloud_file_id` entry containing the google-drive-id of the file to
      sync
    * A `cache_folder` entry telling where the script may cache data

    Args:
        config (dict): the config elements to _write
        version (str): version of the configuration to use

    Returns:
        the config, dict containing the saved/default values
    """
    logger.info('saving config')

    logger.debug(f'version: {version}')

    create_folder_if_needed(get_config_file_path(version).parent)
    with get_config_file_path(version).open("w") as config_file:
        json.dump(config, config_file)

    logger.debug(f'Saved config: {pprint.pformat(config)}')
    return config
Exemple #3
0
def update_local(local_file_path: Path, data: bytearray,
                 cache_folder_path: Path) -> None:
    """Replace the local file content with `data`

    Args:
        local_file_path:
        data:
        cache_folder_path:
    """
    logger.info('Updating local file with cloud one')
    local_file_path.write_bytes(data)
    cache_data_hash(data, 'file.sha', cache_folder_path)
    logger.info('Success')
Exemple #4
0
def update_cloud(data: bytearray, cloud_file_id: str, cache_folder_path: Path,
                 file_name: str) -> None:
    """Replace the data in the cloud with `data`

    Args:
        data (bytearray):
        cloud_file_id(str):
        cache_folder_path(Path):
        file_name(str): name to give to the file on the cloud
    """
    logger.info('Updating cloud file with local one')
    (cache_folder_path / 'tmp').write_bytes(data)
    if drive.update_file(cache_folder_path / 'tmp',
                         cloud_file_id,
                         file_name=file_name).get('id') is not None:
        # Success !
        cache_data_hash(data, 'file.sha', cache_folder_path)
        (cache_folder_path / 'tmp').unlink()
        logger.info('Success')
        logger.debug(f'New sha: {get_hash(data)}')
def _read(version: str= 'default')->dict:
    """Load desired config fom the filesystem

    The config should contain:

    * A `credential_folder_path` entry pointing to a folder
      containing at least a `client_id.json` or `token.json` file. The
      validity of those files will be checked later by the google_services
      package (https://github.com/Retzoh/google_services_wrapper).
    * A `local_file_path` telling where the file to sync is, on the local
      machine
    * A `cloud_file_id` entry containing the google-drive-id of the file to
      sync
    * A `cache_folder` entry telling where the script may cache data

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

    Returns:
        dict containing the saved/default values
    """
    logger.info('loading config')
    logger.debug(f'version: {version}')
    # Setting default values
    config = dict(
        credential_folder_path='',
        local_file_path='',
        cloud_file_id='',
        cache_folder=default_config_path + f'{version}_cache/')

    # Update them with saved ones
    config_file_path = get_config_file_path(version)
    logger.debug(f'config path: {config_file_path}')
    if config_file_path.exists():
        with config_file_path.open("r") as config_file:
            saved_config = json.load(config_file)
        config.update(saved_config)

    logger.debug(f'Loaded config: {pprint.pformat(config)}')
    return config
"""Cli-usage entry-point

"""

import sys
import pprint
from keypass_sync.utilities import logger, log_and_exit
from keypass_sync import config
from keypass_sync.sync_utils import sync, update_cloud, update_local, \
    read_data_from_file, drive


if __name__ == "__main__":
    logger.info('start of the project cration script')
    logger.info(f'script argument: {pprint.pformat(sys.argv)}')

    if len(sys.argv) > 1 and (sys.argv[1] == 'help' or sys.argv[1] == '-h'):
        print('\n'
              'Utility to sync a file on change with a google-drive file.\n\n'
              'Usage:\n\n'
              'python -m keypass_sync [sync] -> sync file with drive ('
              'fails if both were updated since last sync)\n\n'
              'python -m keypass_sync init -> setup SSO & file to think\n\n'
              'python -m keypass_sync force-update cloud -> overwrite the '
              'file on the cloud without checking for conflicts\n\n'
              'python -m keypass_sync force-update local -> overwrite the '
              'local file without checking for conflicts\n\n'
              '\n'
              'All commands can be followed with a `name` argument to '
              'choose between multiple files to sync:\n'
              'python -m keypass_sync sync [name]\n'