Example #1
0
def run(command=None, config_filepath=None, verbose=False, **params):
    """High-level API entry point.
    All 'params' are passed to 'Client.safely_run()'.
    'config_filepath' specifies the path to a custom config file (optional). If
    'verbose' is set, debug level log messages are printed to the terminal.

    This function can be used for scripting. Provide 'command' and 'params'
    according to what the command line interface accepts (consult help via
    `financeager [command] --help`), e.g. {"command": "add", "name":
    "champagne", "value": "99"}.

    :return: UNIX return code (zero for success, non-zero otherwise)
    """
    if verbose:
        make_log_stream_handler_verbose()

    exit_code = FAILURE

    if config_filepath is None and os.path.exists(financeager.CONFIG_FILEPATH):
        config_filepath = financeager.CONFIG_FILEPATH
    try:
        configuration = Configuration(filepath=config_filepath)
    except InvalidConfigError as e:
        logger.error("Invalid configuration: {}".format(e))
        return FAILURE

    date_format = configuration.get_option("FRONTEND", "date_format")
    try:
        _preprocess(params, date_format)
    except PreprocessingError as e:
        logger.error(e)
        return FAILURE

    service_name = configuration.get_option("SERVICE", "name")
    if service_name == "flask":
        init_logger("urllib3")

    client = Client(configuration=configuration,
                    out=Client.Out(logger.info, logger.error))
    success, store_offline = client.safely_run(command, **params)

    if success:
        exit_code = SUCCESS

        # When regular command was successfully executed, attempt to recover
        # offline backup
        try:
            if offline.recover(client):
                logger.info("Recovered offline backup.")
        except OfflineRecoveryError:
            logger.error("Offline backup recovery failed!")
            exit_code = FAILURE

    if store_offline and offline.add(command, **params):
        logger.info("Stored '{}' request in offline backup.".format(command))

    if service_name == "none":
        client.run("stop")

    return exit_code
Example #2
0
    def test_add_recover(self):
        period_name = "123"
        kwargs = dict(name="money", value=111, date="01-31", period=period_name)
        self.assertTrue(add("add", offline_filepath=self.filepath, **kwargs))

        content = _load(self.filepath)

        self.assertIsInstance(content, list)
        self.assertEqual(len(content), 1)
        data = content[0]
        self.assertEqual(data.pop("command"), "add")
        self.assertDictEqual(kwargs, data)

        client = utils.Client()
        self.assertTrue(recover(client, offline_filepath=self.filepath))

        element = client.proxy.run("get", eid=1, period=period_name)["element"]
        self.assertEqual(element["name"], "money")
        self.assertEqual(element["value"], 111)
Example #3
0
def run(command=None, config_filepath=None, verbose=False, **cl_kwargs):
    """High-level API entry point, useful for scripts. Run 'command' passing
    'cl_kwargs' according to what the command line interface accepts (consult
    help via `financeager [command] --help`), e.g. {"command": "add", "name":
    "champagne", "value": "99"}. All kwargs are passed to 'communication.run()'.
    'config' specifies the path to a custom config file (optional). If 'verbose'
    is set, debug level log messages are printed to the terminal.

    :return: UNIX return code (zero for success, non-zero otherwise)
    """
    if verbose:
        make_log_stream_handler_verbose()

    exit_code = FAILURE

    if config_filepath is None and os.path.exists(financeager.CONFIG_FILEPATH):
        config_filepath = financeager.CONFIG_FILEPATH
    try:
        configuration = Configuration(filepath=config_filepath)
    except InvalidConfigError as e:
        logger.error("Invalid configuration: {}".format(e))
        return FAILURE

    backend_name = configuration.get_option("SERVICE", "name")
    communication_module = communication.module(backend_name)

    proxy_kwargs = {}
    if backend_name == "flask":
        init_logger("urllib3")
        proxy_kwargs["http_config"] = configuration.get_option("SERVICE:FLASK")
    else:  # 'none' is the only other option
        proxy_kwargs["data_dir"] = financeager.DATA_DIR

    # Indicate whether to store request offline, if failed
    store_offline = False

    proxy = communication_module.proxy(**proxy_kwargs)

    try:
        logger.info(
            communication.run(proxy,
                              command,
                              default_category=configuration.get_option(
                                  "FRONTEND", "default_category"),
                              date_format=configuration.get_option(
                                  "FRONTEND", "date_format"),
                              **cl_kwargs))
        if offline.recover(proxy):
            logger.info("Recovered offline backup.")
        exit_code = SUCCESS
    except OfflineRecoveryError:
        logger.error("Offline backup recovery failed!")
    except (PreprocessingError, InvalidRequest) as e:
        # Command is erroneous and hence not stored offline
        logger.error(e)
    except CommunicationError as e:
        logger.error(e)
        store_offline = True
    except Exception:
        logger.exception("Unexpected error")
        store_offline = True

    if store_offline and offline.add(command, **cl_kwargs):
        logger.info("Stored '{}' request in offline backup.".format(command))

    if backend_name == "none":
        communication.run(proxy, "stop")

    return exit_code
Example #4
0
 def test_no_recover(self):
     self.assertFalse(recover(None, offline_filepath=self.filepath))