Example #1
0
    def parse(self, string):
        """
        Returns
        -------
        powl.actiondata.TransactionData
            Contains data to perform a transaction action.

        Raises
        ------
        ValueError
            If amount is not a float.
            If a value for TransactionData is missing.
        """
        data = actiondata.TransactionData()
        params = string.split(self._DELIMITER, self._MAX_SPLITS)

        if len(params) < self._NUM_PARAMS:
            msg = "not enough arguments from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        data.debit = params[self._POSITION_DEBIT]
        data.credit = params[self._POSITION_CREDIT]
        data.amount = params[self._POSITION_AMOUNT]
        data.memo = params[self._POSITION_MEMO]

        try:
            float(data.amount)
        except ValueError:
            msg = "amount ({0}) is not a number".format(data.amount)
            err = exception.create(ValueError, msg)
            raise err

        return data
Example #2
0
    def parse(self, string):
        """
        Returns
        -------
        powl.actiondata.TransactionData
            Contains data to perform a transaction action.

        Raises
        ------
        ValueError
            If amount is not a float.
            If a value for TransactionData is missing.
        """
        data = actiondata.TransactionData()
        params = string.split(self._TOKEN_FLAG)

        for param in params:
            if re.match(self._TOKEN_DEBIT, param):
                data.debit = re.sub(self._TOKEN_DEBIT, "", param)
                data.debit = data.debit.strip()
            elif re.match(self._TOKEN_CREDIT, param):
                data.credit = re.sub(self._TOKEN_CREDIT, "", param)
                data.credit = data.credit.strip()
            elif re.match(self._TOKEN_AMOUNT, param):
                data.amount = re.sub(self._TOKEN_AMOUNT, "", param)
                data.amount = data.amount.strip()
            elif re.match(self._TOKEN_MEMO, param):
                data.memo = re.sub(self._TOKEN_MEMO, "", param)
                data.memo = data.memo.replace('"', "")
                data.memo = data.memo.strip()

        if not data.debit:
            msg = "debit is missing from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        if not data.credit:
            msg = "credit is missing from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        if not data.amount:
            msg = "amount is missing from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        if not data.memo:
            msg = "memo is missing from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        try:
            float(data.amount)
        except ValueError as err:
            message = "amount ({0}) is not a number".format(data.amount)
            exception.add_message(err, message)
            raise

        return data
Example #3
0
    def parse(self, string):
        """
        Returns
        -------
        powl.actiondata.BodyCompositionData
            Contains data to perform a body composition action.

        Raises
        ------
        ValueError
            If mass or fat percentage is not a float.
            If a value for BodyCompositionData is missing.
        """
        data = actiondata.BodyCompositionData()
        params = string.split(self._TOKEN_FLAG)

        for param in params:
            if re.match(self._TOKEN_MASS, param):
                data.mass = re.sub(self._TOKEN_MASS, "", param)
                data.mass = data.mass.strip()
            elif re.match(self._TOKEN_FAT, param):
                data.fat_percentage = re.sub(self._TOKEN_FAT, "", param)
                data.fat_percentage = data.fat_percentage.strip()

        if not data.mass:
            msg = "mass was not parsed from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        if not data.fat_percentage:
            msg = "fat percentage was not parsed " + "from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        try:
            float(data.mass)
        except ValueError as err:
            msg = "mass ({0}) is not a number".format(data.mass)
            exception.add_message(err, msg)
            raise

        try:
            float(data.fat_percentage)
        except ValueError as err:
            msg = "fat percentage ({0}) ".format(data.fat_percentage) + "is not a number"
            exception.add_message(err, msg)
            raise

        return data
Example #4
0
 def test__create__return_is_input_type(self):
     """
     Test that the returned exception is the correct type.
     """
     exception_type = ValueError
     err = exception.create(exception_type, "")
     self.assertEqual(exception_type, type(err))
Example #5
0
 def _assert_logged_in(self):
     """
     Raise exception if not logged in to IMAP server.
     """
     if not self._logged_in:
         errmsg = _ERRMSG_NOT_LOGGED_IN
         err = exception.create(ValueError, errmsg)
         raise err
Example #6
0
 def _assert_connected(self):
     """
     Raise exception if not connected to IMAP server.
     """
     if not self._imap:
         errmsg = _ERRMSG_NOT_CONNECTED
         err = exception.create(ValueError, errmsg)
         raise err
    def _get_transfer_account(self, debit, credit):
        """
        Get the associated QIF account from the debit and credit keys.

        Parameters
        ----------
        debit : str
            Account key for the debit of a transaction.
        credit : str
            Account key for the credit of a transaction.

        Raises
        ------
        KeyError
            If neither key has an associated QIF file.
            If neither key has an associated QIF account.

        Notes
        -----
        Credit key has priority so if both debit and credit key has an
        associated QIF account than the QIF account associated with the
        credit key is returned.

        This is linked with get_qif_file. If the transfer account returned
        from this is from the credit key then the QIF file must be from the
        debit key and vice versa.
        """
        if debit in self._files:
            key = credit
        elif credit in self._files:
            key = debit
        else:
            msg = (
                "neither debit key ({0}) ".format(debit)
                + "or credit key ({0}) ".format(credit)
                + "has an associated QIF file"
            )
            err = exception.create(KeyError, msg)
            raise err

        if key in self._accounts:
            return self._accounts[key]
        else:
            msg = "account key ({0}) ".format(key) + "does not have has an associated QIF account"
            err = exception.create(KeyError, msg)
            raise err
Example #8
0
 def _select_mailbox(self):
     """
     Select a mailbox folder.
     """
     result, response = self._imap.select(self._mailbox)
     if result == "NO":
         errmsg = _ERRMSG_INVALID_MAILBOX.format(self._mailbox)
         err = exception.create(ValueError, errmsg)
         raise err
Example #9
0
 def test__create__first_arg_is_message_preceded_by_type(self):
     """
     Test that the first argument is input message preceded by <type>:.
     """
     exception_type = ValueError
     input_message = "this is an error message"
     expected_message = ("{0}: {1}".format(exception_type.__name__,
                                           input_message))
     err = exception.create(exception_type, input_message)
     actual_message = err.args[0]
     self.assertEqual(expected_message, actual_message)
    def __init__(self, log, files, account_types, assets, liabilities, revenues, expenses):
        """
        Parameters
        ----------
        log : powl.log.Log
            Used to log.
        files : dict of powl.filesystem.File
            Map of account key to files. Every key in files must exist in
            either of assets, liabilities, revenues, or expenses.
        account_types : dict
            Map of account key to QIF account types.
        assets : dict
            Map of account key to Assets.
        liabilities : dict
            Map of account key to Liabilitess.
        revenues : dict
            Map of account key to Revenuess.
        expenses : dict
            Map of account key to Expensess.

        Notes
        -----
        An account key is a string that maps to a QIF account.
        Multiple account key words can map to the same account.
        For example "ent" can map to "Expenses:Entertainment" and
        "entertainment" can also map to "Expenses:Entertainment".

        Raises
        ------
        ValueError
            If a key is files does not have a key in any of assets,
            liabilities, revenues, or expenses.
        """
        self._log = log
        self._files = files
        self._account_types = account_types
        self._assets = assets
        self._liabilities = liabilities
        self._revenues = revenues
        self._expenses = expenses

        self._accounts = dict(
            self._assets.items() + self._liabilities.items() + self._revenues.items() + self._expenses.items()
        )

        for key, value in self._files.items():
            if key not in self._accounts.keys():
                msg = (
                    "account key ({0}) ".format(key)
                    + "for file ({0}) ".format(value.filename)
                    + "does not have has an associated QIF account"
                )
                err = exception.create(ValueError, msg)
                raise err
Example #11
0
    def parse(self, string):
        """
        Returns
        -------
        powl.actiondata.BodyCompositionData
            Contains data to perform a body composition action.

        Raises
        ------
        ValueError
            If mass or fat percentage is not a float.
            If a value for BodyCompositionData is missing.
        """
        data = actiondata.BodyCompositionData()
        params = re.split(self._DELIMITER, string, self._MAX_SPLITS)

        if len(params) < self._NUM_PARAMS:
            msg = "not enough arguments from ({0})".format(string)
            err = exception.create(ValueError, msg)
            raise err

        mass = params[self._POSITION_MASS]
        fat_percentage = params[self._POSITION_FAT]

        try:
            data.mass = float(mass)
        except ValueError as err:
            msg = "mass ({0}) is not a number".format(mass)
            exception.add_message(err, msg)
            raise

        try:
            data.fat_percentage = float(fat_percentage)
        except ValueError as err:
            msg = "fat percentage ({0}) ".format(fat_percentage) + "is not a number"
            exception.add_message(err, msg)
            raise

        return data
    def _format_amount(self, debit, amount):
        """
        Convert amount to QIF format based on debit.

        Parameters
        ----------
        debit : str
            Account key for the debit of a transaction.
        amount : str or float
            Amount of the transaction.

        Returns
        -------
        str
            Formatted amount to use in QIF file.

        Raises
        ------
        ValueError
            If amount cannot be converted to a float.
        KeyError
            If debit key is not an account.
        """
        try:
            formatted_amount = "{0:.2f}".format(float(amount))
        except ValueError as err:
            msg = "amount ({0}) cannot be converted to float".format(amount)
            exception.add_message(err, msg)
            raise

        if debit in self._expenses:
            # Amount should be negative.
            return "-" + formatted_amount
        elif debit in self._accounts:
            return formatted_amount
        else:
            msg = "account key ({0}) does not exist".format(debit)
            err = exception.create(KeyError, msg)
            raise err
Example #13
0
 def _assert_not_empty(self, value, errmsg):
     """
     """
     if not value:
         err = exception.create(ValueError, errmsg)
         raise err