Exemple #1
0
    def testFieldsSecured(self):
        if not ofxclient.config.KEYRING_AVAILABLE:
            return

        # always skip these for now
        return

        c = OfxConfig(file_name=self.temp_file.name)

        i = Institution(
                id='1',
                org='org',
                url='url',
                username='******',
                password='******'
        )
        a = CreditCardAccount(institution=i, number='12345')
        c.add_account(a)

        self.assertTrue(
            c.parser.is_secure_option(a.local_id(), 'institution.username')
        )
        self.assertTrue(
            c.parser.is_secure_option(a.local_id(), 'institution.password')
        )
 def test_empty_run(self):
     for lgr in [LedgerPython(os.path.join('fixtures', 'checking.lgr')),
                 HLedger(os.path.join('fixtures', 'checking.lgr')),
                 Ledger(os.path.join('fixtures', 'checking.lgr'), no_pipe=True)]:
         config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
         acct = config.accounts()[0]
         acct.download = Mock(return_value=file(os.path.join('fixtures', 'checking.ofx')))
         config.accounts = Mock(return_value=[acct])
         sync(lgr, config, 7)
Exemple #3
0
def test_run():
    config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
    acct = config.accounts()[0]
    acct.download = Mock(side_effect=lambda *args, **kwargs: open(
        os.path.join("fixtures", "checking.ofx"), "rb"))
    config.accounts = Mock(return_value=[acct])
    run(["-l", os.path.join("fixtures", "empty.lgr")], config)
    acct.download.assert_has_calls([call(days=7), call(days=14)])
    assert config.accounts.call_count == 1
Exemple #4
0
 def test_run(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     acct = config.accounts()[0]
     acct.download = Mock(side_effect=lambda *args, **kwargs: file(
         os.path.join('fixtures', 'checking.ofx')))
     config.accounts = Mock(return_value=[acct])
     run(['-l', os.path.join('fixtures', 'empty.lgr')], config)
     acct.download.assert_has_calls([call(days=7), call(days=14)])
     self.assertEqual(config.accounts.call_count, 1)
Exemple #5
0
    def testAddAccount(self):
        c = OfxConfig(file_name=self.temp_file.name)

        i = Institution(id='1',org='org',url='url',username='******',password='******')
        a = CreditCardAccount(institution=i,number='12345')

        c.add_account(a)
        self.assertEqual( len(c.accounts()), 1 )
        self.assertEqual( c.account(a.local_id()).local_id(), a.local_id() )
Exemple #6
0
 def test_run(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     acct = config.accounts()[0]
     acct.download = Mock(side_effect=lambda *args, **kwargs:
                          open(os.path.join('fixtures', 'checking.ofx')))
     config.accounts = Mock(return_value=[acct])
     run(['-l', os.path.join('fixtures', 'empty.lgr')], config)
     acct.download.assert_has_calls([call(days=7), call(days=14)])
     self.assertEqual(config.accounts.call_count, 1)
Exemple #7
0
 def test_no_ledger(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     acct = config.accounts()[0]
     acct.download = Mock(side_effect=lambda *args, **kwargs:
                          file(os.path.join('fixtures', 'checking.ofx')))
     config.accounts = Mock(return_value=[acct])
     with patch('ledgerautosync.cli.find_ledger_file', return_value=None):
         with patch('sys.stderr', new_callable=StringIO) as mock_stdout:
             run([], config)
             self.assertEquals(mock_stdout.getvalue(), 'LEDGER_FILE environment variable not set, and no .ledgerrc file found, and -l argument was not supplied: running with deduplication disabled. All transactions will be printed!')
Exemple #8
0
 def test_no_ledger(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     acct = config.accounts()[0]
     acct.download = Mock(side_effect=lambda *args, **kwargs:
                          open(os.path.join('fixtures', 'checking.ofx')))
     config.accounts = Mock(return_value=[acct])
     with patch('ledgerautosync.cli.find_ledger_file', return_value=None):
         with patch('sys.stderr', new_callable=StringIO) as mock_stdout:
             run([], config)
             self.assertEqual(
                 mock_stdout.getvalue(),
                 'LEDGER_FILE environment variable not set, and no .ledgerrc file found, and -l argument was not supplied: running with deduplication disabled. All transactions will be printed!\n')
Exemple #9
0
def test_no_ledger():
    config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
    acct = config.accounts()[0]
    acct.download = Mock(side_effect=lambda *args, **kwargs: open(
        os.path.join("fixtures", "checking.ofx"), "rb"))
    config.accounts = Mock(return_value=[acct])
    with patch("ledgerautosync.cli.find_ledger_file", return_value=None):
        with patch("sys.stderr", new_callable=StringIO) as mock_stdout:
            run([], config)
            assert (
                mock_stdout.getvalue() ==
                "LEDGER_FILE environment variable not set, and no .ledgerrc file found, and -l argument was not supplied: running with deduplication disabled. All transactions will be printed!\n"
            )
Exemple #10
0
def main():
    log.info("Started...")

    conn = connect(config_database_connect)
    cur = conn.cursor(cursor_factory=DictCursor)
    sql = "select * from accounts_types where download=true"
    cur.execute(sql)
    banks = cur.fetchall()
    for bank in banks:
        try:
            log.info("Downloading: " + " " + bank['description'])
            GlobalConfig = OfxConfig()
            a = GlobalConfig.account(bank['id'])
            ofxdata = a.download(days=0)
            f = open(path.expanduser('~/tmp/ofxdata.tmp'), 'w')
            f.write(ofxdata.read())
            f.close()
            f = open(path.expanduser('~/tmp/ofxdata.tmp'), 'r')
            parsed = OfxParser.parse(f)
            f.close()
            log.info("OfxParser complete")
            positions = {}
            for pos in parsed.account.statement.positions:
                positions[pos.security] = round(pos.units * pos.unit_price, 2)
                log.info("Downloaded: " + str(bank['description']) + " " +
                         str(pos.security))

            sql = "select * from accounts where type=" + str(bank['type'])
            cur.execute(sql)
            accounts = cur.fetchall()
            for account in accounts:
                if account['name'] not in positions:
                    raise Exception('account ' + account['name'] +
                                    ' not present in download')
                log.info(bank['description'] + '\t' + account['name_local'] +
                         '\t' + str(positions[account['name']]))
                sql = "update constituents set value=" + str(
                    positions[account['name']]
                ) + "where symbol='" + account['name_local'] + "'"
                cur.execute(sql)
                conn.commit()
                log.info("Set: " + str(account['name_local']))

        except Exception as err:
            log.exception(err)
            log.error("Failed loading for bank: " + bank['description'])

    # Close the db
    cur.close()
    conn.close()
    log.info("Completed")
Exemple #11
0
 def test_filter_account(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     foo = next(acct for acct in config.accounts()
                if acct.description == 'Assets:Savings:Foo')
     bar = next(acct for acct in config.accounts()
                if acct.description == 'Assets:Checking:Bar')
     foo.download = Mock(side_effect=lambda *args, **kwargs:
                         open(os.path.join('fixtures', 'checking.ofx'), 'rb'))
     bar.download = Mock()
     config.accounts = Mock(return_value=[foo, bar])
     run(['-l', os.path.join('fixtures', 'checking.lgr'),
          '-a', 'Assets:Savings:Foo'], config)
     foo.download.assert_has_calls([call(days=7)])
     bar.download.assert_not_called()
Exemple #12
0
def main():
    log.info("Started...")
    config = ConfigParser.SafeConfigParser()
    config.read(os.path.expanduser('~/.Kumamon'))
    connect = config.get('Database','Connect')
        
    conn = psycopg2.connect( connect )
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    sql = "select * from accounts_types where download=true";
    cur.execute(sql)
    banks = cur.fetchall()   
    for bank in banks:
        try:
            log.info("Downloading: " + " " + bank['description'])
            GlobalConfig = OfxConfig()
            a = GlobalConfig.account(bank['id'])
            ofxdata = a.download(days=0)
            f = open(os.path.expanduser('~/tmp/ofxdata.tmp'), 'w')
            f.write(ofxdata.read())
            f.close()
            f = open(os.path.expanduser('~/tmp/ofxdata.tmp'), 'r')
            parsed = OfxParser.parse(f)
            f.close()
            log.info("OfxParser complete")
            positions = {}
            for pos in parsed.account.statement.positions:
                positions[pos.security] = round(pos.units * pos.unit_price, 2)
                log.info("Downloaded: " + str(bank['description']) + " " + str(pos.security))
            
            sql = "select * from accounts where type=" + str(bank['type']);
            cur.execute(sql)
            accounts = cur.fetchall()
            for account in accounts:
                if account['name'] not in positions:
                    raise Exception('account ' + account['name'] + ' not present in download')
                log.info( bank['description'] + '\t' + account['name_local'] + '\t' + str(positions[account['name']]) ) 
                sql = "update constituents set value=" + str(positions[account['name']]) + "where symbol='" + account['name_local'] + "'"
                cur.execute(sql)
                conn.commit()
                log.info("Set: " + str(account['name_local']))
                
        except Exception as err:
            log.exception(err)
            log.error("Failed loading for bank: " + bank['description'])
            send_mail_html("FAILURE:  Ofxdownload.py", str( err ) )        
    
    # Close the db
    cur.close()
    conn.close()
    log.info("Completed")
Exemple #13
0
    def testFieldsRemainUnsecure(self):
        if not ofxclient.config.KEYRING_AVAILABLE:
            return

        c = OfxConfig(file_name=self.temp_file.name)
        i = Institution(
                id='1',
                org='org',
                url='url',
                username='******',
                password='******'
        )
        a = CreditCardAccount(institution=i, number='12345')
        c.add_account(a)

        # pretend the user put their password in there in the clear on purpose
        c.parser.remove_option(a.local_id(), 'institution.password')
        c.parser.set(a.local_id(), 'institution.password', 'pass')
        c.save()

        c = OfxConfig(file_name=self.temp_file.name)
        self.assertTrue(
            c.parser.is_secure_option(a.local_id(), 'institution.username')
        )
        self.assertFalse(
            c.parser.is_secure_option(a.local_id(), 'institution.password')
        )
Exemple #14
0
 def test_filter_account(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     foo = next(acct for acct in config.accounts()
                if acct.description == 'Assets:Savings:Foo')
     bar = next(acct for acct in config.accounts()
                if acct.description == 'Assets:Checking:Bar')
     foo.download = Mock(side_effect=lambda *args, **kwargs:
                         open(os.path.join('fixtures', 'checking.ofx')))
     bar.download = Mock()
     config.accounts = Mock(return_value=[foo, bar])
     run(['-l', os.path.join('fixtures', 'checking.lgr'),
          '-a', 'Assets:Savings:Foo'], config)
     foo.download.assert_has_calls([call(days=7)])
     bar.download.assert_not_called()
Exemple #15
0
def run():
    global GlobalConfig

    parser = argparse.ArgumentParser(prog="ofxclient")
    parser.add_argument("-a", "--account")
    parser.add_argument("-d", "--download", type=argparse.FileType("wb", 0))
    parser.add_argument("-o", "--open", action="store_true")
    parser.add_argument("-v", "--verbose", action="store_true")
    parser.add_argument("-c", "--config", help="config file path")
    parser.add_argument(
        "--download-days",
        default=DOWNLOAD_DAYS,
        type=int,
        help="number of days to download (default: %s)" % DOWNLOAD_DAYS,
    )
    parser.add_argument(
        "--ofx-version",
        default=DEFAULT_OFX_VERSION,
        type=int,
        help="ofx version to use for new accounts (default: %s)" % DEFAULT_OFX_VERSION,
    )
    args = parser.parse_args()

    if args.config:
        GlobalConfig = OfxConfig(file_name=args.config)
    else:
        GlobalConfig = OfxConfig()

    accounts = GlobalConfig.accounts()
    account_ids = [a.local_id() for a in accounts]

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if args.download:
        if accounts:
            if args.account:
                a = GlobalConfig.account(args.account)
                ofxdata = a.download(days=args.download_days)
            else:
                ofxdata = combined_download(accounts, days=args.download_days)
            args.download.write(ofxdata.read())
            if args.open:
                open_with_ofx_handler(args.download.name)
            sys.exit(0)
        else:
            print("no accounts configured")

    main_menu(args)
Exemple #16
0
 def test_run_csv_file(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     run([
         '-a', 'Paypal', '-l',
         os.path.join('fixtures', 'empty.lgr'),
         os.path.join('fixtures', 'paypal.csv')
     ], config)
Exemple #17
0
    def testFieldsSecured(self):
        if not ofxclient.config.KEYRING_AVAILABLE:
            return

        c = OfxConfig(file_name=self.temp_file.name)

        i = Institution(id='1',
                        org='org',
                        url='url',
                        username='******',
                        password='******')
        a = CreditCardAccount(institution=i, number='12345')
        c.add_account(a)

        self.assertTrue(
            c.parser.is_secure_option(a.local_id(), 'institution.username'))
        self.assertTrue(
            c.parser.is_secure_option(a.local_id(), 'institution.password'))
Exemple #18
0
    def testFileCreated(self):
        file_name = self.temp_file.name
        self.temp_file.close()

        self.assertFalse(os.path.exists(file_name))

        c = OfxConfig(file_name=file_name)
        self.assertTrue(os.path.exists(file_name))

        os.remove(file_name)
Exemple #19
0
def test_run_csv_file():
    config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
    run(
        [
            "-a",
            "Paypal",
            "-l",
            os.path.join("fixtures", "empty.lgr"),
            os.path.join("fixtures", "paypal.csv"),
        ],
        config,
    )
Exemple #20
0
def test_filter_account():
    config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
    foo = next(acct for acct in config.accounts()
               if acct.description == "Assets:Savings:Foo")
    bar = next(acct for acct in config.accounts()
               if acct.description == "Assets:Checking:Bar")
    foo.download = Mock(side_effect=lambda *args, **kwargs: open(
        os.path.join("fixtures", "checking.ofx"), "rb"))
    bar.download = Mock()
    config.accounts = Mock(return_value=[foo, bar])
    run(
        [
            "-l",
            os.path.join("fixtures", "checking.lgr"),
            "-a",
            "Assets:Savings:Foo",
        ],
        config,
    )
    foo.download.assert_has_calls([call(days=7)])
    bar.download.assert_not_called()
Exemple #21
0
def run():
    global GlobalConfig

    parser = argparse.ArgumentParser(prog='ofxclient')
    parser.add_argument('-a', '--account')
    parser.add_argument('-d', '--download', type=argparse.FileType('wb', 0))
    parser.add_argument('-o', '--open', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('-c', '--config', help='config file path')
    parser.add_argument('--download-days', default=DOWNLOAD_DAYS, type=int, help='number of days to download (default: %s)' % DOWNLOAD_DAYS)
    parser.add_argument('--ofx-version', default=DEFAULT_OFX_VERSION, type=int, help='ofx version to use for new accounts (default: %s)' % DEFAULT_OFX_VERSION)
    args = parser.parse_args()

    if args.config:
        GlobalConfig = OfxConfig(file_name=args.config)
    else:
        GlobalConfig = OfxConfig()

    accounts = GlobalConfig.accounts()
    account_ids = [a.local_id() for a in accounts]

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if args.download:
        if accounts:
            if args.account:
                a = GlobalConfig.account(args.account)
                ofxdata = a.download(days=args.download_days)
            else:
                ofxdata = combined_download(accounts, days=args.download_days)
            args.download.write(ofxdata.read().encode())
            if args.open:
                open_with_ofx_handler(args.download.name)
            sys.exit(0)
        else:
            print("no accounts configured")

    main_menu(args)
Exemple #22
0
def test_no_institution_no_fid(ledger):
    with pytest.raises(EmptyInstitutionException):
        config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
        run(
            [
                os.path.join("fixtures", "no-institution.ofx"),
                "-l",
                os.path.join("fixtures", "empty.lgr"),
                "-a",
                "Assets:Savings:Foo",
            ],
            config,
        )
Exemple #23
0
    def testLoadFromFile(self):
        c = OfxConfig(file_name=self.temp_file.name)
        i = Institution(id='1',
                        org='org',
                        url='url',
                        username='******',
                        password='******')
        a = CreditCardAccount(institution=i, number='12345')
        c.add_account(a)
        c.save()

        c = OfxConfig(file_name=self.temp_file.name)
        got = c.account(a.local_id())
        self.assertEqual(len(c.accounts()), 1)
        self.assertEqual(got.local_id(), a.local_id())
        self.assertEqual(got.number, a.number)
        self.assertEqual(got.institution.local_id(), a.institution.local_id())
        self.assertEqual(got.institution.id, a.institution.id)
        self.assertEqual(got.institution.org, a.institution.org)
        self.assertEqual(got.institution.url, a.institution.url)
        self.assertEqual(got.institution.username, a.institution.username)
        self.assertEqual(got.institution.password, a.institution.password)
Exemple #24
0
    def testLoadFromFile(self):
        c = OfxConfig(file_name=self.temp_file.name)
        i = Institution(id='1',org='org',url='url',username='******',password='******')
        a = CreditCardAccount(institution=i,number='12345')
        c.add_account(a)
        c.save()

        c = OfxConfig(file_name=self.temp_file.name)
        got = c.account(a.local_id())
        self.assertEqual( len(c.accounts()), 1 )
        self.assertEqual( got.local_id(), a.local_id() )
        self.assertEqual( got.number, a.number )
        self.assertEqual( got.institution.local_id(), a.institution.local_id() )
        self.assertEqual( got.institution.id, a.institution.id )
        self.assertEqual( got.institution.org, a.institution.org )
        self.assertEqual( got.institution.url, a.institution.url )
        self.assertEqual( got.institution.username, a.institution.username )
        self.assertEqual( got.institution.password, a.institution.password )
Exemple #25
0
    def testAddAccount(self):
        c = OfxConfig(file_name=self.temp_file.name)

        i = Institution(id='1',
                        org='org',
                        url='url',
                        username='******',
                        password='******')
        a = CreditCardAccount(institution=i, number='12345')

        c.add_account(a)
        self.assertEqual(len(c.accounts()), 1)
        self.assertEqual(c.account(a.local_id()).local_id(), a.local_id())
Exemple #26
0
def run():
    global GlobalConfig

    parser = argparse.ArgumentParser(prog='ofxclient')
    parser.add_argument('-a', '--account')
    parser.add_argument('-d', '--download', type=argparse.FileType('wb', 0))
    parser.add_argument('-o', '--open', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('-c', '--config', help='config file path')
    parser.add_argument('--download-days',
                        default=DOWNLOAD_DAYS,
                        type=int,
                        help='number of days to download (default: %s)' %
                        DOWNLOAD_DAYS)
    parser.add_argument(
        '--ofx-version',
        default=DEFAULT_OFX_VERSION,
        type=int,
        help='ofx version to use for new accounts (default: %s)' %
        DEFAULT_OFX_VERSION)
    args = parser.parse_args()

    if args.config:
        GlobalConfig = OfxConfig(file_name=args.config)
    else:
        GlobalConfig = OfxConfig()

    accounts = GlobalConfig.accounts()
    account_ids = [a.local_id() for a in accounts]

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if args.download:
        if accounts:
            if args.account:
                a = GlobalConfig.account(args.account)
                ofxdata = a.download(days=args.download_days)
            else:
                ofxdata = combined_download(accounts, days=args.download_days)
            if IS_PYTHON_2:
                args.download.write(ofxdata.read())
            else:
                args.download.write(ofxdata.read().encode())
            if args.open:
                open_with_ofx_handler(args.download.name)
            sys.exit(0)
        else:
            print("no accounts configured")

    main_menu(args)
Exemple #27
0
def run():
    global GlobalConfig

    parser = argparse.ArgumentParser(prog='ofxclient')
    parser.add_argument('-a', '--account')
    parser.add_argument('-d', '--download', type=argparse.FileType('wb', 0))
    parser.add_argument('-o', '--open', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('-c', '--config', help='config file path')
    args = parser.parse_args()

    if args.config:
        GlobalConfig = OfxConfig(file_name=args.config)
    else:
        GlobalConfig = OfxConfig()

    accounts = GlobalConfig.accounts()
    account_ids = [a.local_id() for a in accounts]

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if args.download:
        if accounts:
            if args.account:
                a = GlobalConfig.account(args.account)
                ofxdata = a.download(days=DOWNLOAD_DAYS)
            else:
                ofxdata = combined_download(accounts, days=DOWNLOAD_DAYS)
            args.download.write(ofxdata.read())
            if args.open:
                open_with_ofx_handler(args.download.name)
            sys.exit(0)
        else:
            print("no accounts configured")

    main_menu()
Exemple #28
0
import logging
import os
import os.path
import sys

from ofxhome import OFXHome

from ofxclient.account import BankAccount, BrokerageAccount, CreditCardAccount
from ofxclient.config import OfxConfig
from ofxclient.institution import Institution
from ofxclient.util import combined_download

AUTO_OPEN_DOWNLOADS = 1
DOWNLOAD_DAYS = 30

GlobalConfig = OfxConfig()


def run():
    accounts = GlobalConfig.accounts()
    account_ids = [a.local_id() for a in accounts]

    parser = argparse.ArgumentParser(prog='ofxclient')
    parser.add_argument('-a', '--account', choices=account_ids)
    parser.add_argument('-d', '--download', type=argparse.FileType('wb', 0))
    parser.add_argument('-o', '--open', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
Exemple #29
0
    def testResecuredAfterEncryptAccount(self):
        if not ofxclient.config.KEYRING_AVAILABLE:
            return

        c = OfxConfig(file_name=self.temp_file.name)
        i = Institution(
                id='1',
                org='org',
                url='url',
                username='******',
                password='******'
        )
        a1 = CreditCardAccount(institution=i, number='12345')
        c.add_account(a1)
        a2 = CreditCardAccount(institution=i, number='67890')
        c.add_account(a2)

        # pretend the user put their password in there in the clear on purpose
        # to fix something... and then wants it to be resecured later on
        c.parser.remove_option(a1.local_id(), 'institution.password')
        c.parser.set(a1.local_id(), 'institution.password', 'pass')
        c.save()

        c = OfxConfig(file_name=self.temp_file.name)
        self.assertEqual(len(c.accounts()), 2)
        self.assertEqual(len(c.encrypted_accounts()), 1)
        self.assertEqual(len(c.unencrypted_accounts()), 1)
        self.assertTrue(
            c.parser.is_secure_option(a1.local_id(), 'institution.username')
        )
        self.assertFalse(
            c.parser.is_secure_option(a1.local_id(), 'institution.password')
        )

        c.encrypt_account(a1.local_id())
        self.assertEqual(len(c.accounts()), 2)
        self.assertEqual(len(c.encrypted_accounts()), 2)
        self.assertEqual(len(c.unencrypted_accounts()), 0)
        self.assertTrue(
            c.parser.is_secure_option(a1.local_id(), 'institution.username')
        )
        self.assertTrue(
            c.parser.is_secure_option(a1.local_id(), 'institution.password')
        )
Exemple #30
0
def test_no_ledger_arg():
    with pytest.raises(LedgerAutosyncException):
        config = OfxConfig(os.path.join("fixtures", "ofxclient.ini"))
        run(["-l", os.path.join("fixtures", "checking.lgr"), "-L"], config)
Exemple #31
0
#!/usr/bin/env python3

import os, logging

from datetime import datetime
from dateutil import parser
from ofxclient.config import OfxConfig

from raw import Account, Entry
from .inferencing import inferTransactionFromEntry

ofxConfig = OfxConfig(file_name=os.environ['LITTLEFINGER_OFX'])
logging.info('Using OFX Config file: %s', os.environ['LITTLEFINGER_OFX'])


def parseToDate(value):
    try:
        if isinstance(value, datetime):
            return value

        return parser.parse(value)

    except Exception as e:
        logging.warning("Could not parse value (%s) a valid date: %s", value,
                        e)
        return None


def parseToInt(value):
    try:
        if value is None or value == "":
Exemple #32
0
 def test_no_ledger_arg(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     run(['-l', os.path.join('fixtures', 'checking.lgr'), '-L'], config)
Exemple #33
0
def run(args=None, config=None):
    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Synchronize ledger.')
    parser.add_argument('-m',
                        '--max',
                        type=int,
                        default=90,
                        help='maximum number of days to process')
    parser.add_argument('-r',
                        '--resync',
                        action='store_true',
                        default=False,
                        help='do not stop until max days reached')
    parser.add_argument('PATH',
                        nargs='?',
                        help='do not sync; import from OFX \
file')
    parser.add_argument('-a',
                        '--account',
                        type=str,
                        default=None,
                        help='sync only the named account; \
if importing from file, set account name for import')
    parser.add_argument('-l',
                        '--ledger',
                        type=str,
                        default=None,
                        help='specify ledger file to READ for syncing')
    parser.add_argument('-i',
                        '--indent',
                        type=int,
                        default=4,
                        help='number of spaces to use for indentation')
    parser.add_argument('--initial',
                        action='store_true',
                        default=False,
                        help='create initial balance entries')
    parser.add_argument('--fid',
                        type=int,
                        default=None,
                        help='pass in fid value for OFX files that do not \
supply it')
    parser.add_argument('--unknown-account',
                        type=str,
                        dest='unknownaccount',
                        default=None,
                        help='specify account name to use when one can\'t be \
found by payee')
    parser.add_argument('--assertions',
                        action='store_true',
                        default=False,
                        help='create balance assertion entries')
    parser.add_argument('-d',
                        '--debug',
                        action='store_true',
                        default=False,
                        help='enable debug logging')
    parser.add_argument('--hledger',
                        action='store_true',
                        default=False,
                        help='force use of hledger (on by default if invoked \
as hledger-autosync)')
    parser.add_argument('--slow',
                        action='store_true',
                        default=False,
                        help='use slow, but possibly more robust, method of \
calling ledger (no subprocess)')
    parser.add_argument('--which',
                        action='store_true',
                        default=False,
                        help='display which version of ledger (cli), hledger, \
or ledger (python) will be used by ledger-autosync to check for previous \
transactions')
    args = parser.parse_args(args)
    if sys.argv[0][-16:] == "hledger-autosync":
        args.hledger = True

    ledger_file = None
    if args.ledger:
        ledger_file = args.ledger
    else:
        ledger_file = find_ledger_file()
    if args.debug:
        logging.basicConfig(level=logging.DEBUG)
    if args.hledger:
        ledger = HLedger(ledger_file)
    elif args.slow:
        ledger = Ledger(ledger_file=ledger_file, no_pipe=True)
    else:
        ledger = mk_ledger(ledger_file)

    if args.which:
        sys.stderr.write("ledger-autosync is using ")
        if type(ledger) == Ledger:
            sys.stderr.write("ledger (cli)\n")
        elif type(ledger) == HLedger:
            sys.stderr.write("hledger\n")
        elif type(ledger) == LedgerPython:
            sys.stderr.write("ledger.so (python)\n")
        exit()

    if args.PATH is None:
        if config is None:
            config_dir = os.environ.get(
                'XDG_CONFIG_HOME',
                os.path.join(os.path.expanduser("~"), '.config'))
            config_file = os.path.join(config_dir, 'ofxclient.ini')
            if (os.path.exists(config_file)):
                config = OfxConfig(file_name=config_file)
            else:
                config = OfxConfig()
        accounts = config.accounts()
        if args.account:
            accounts = [
                acct for acct in accounts if acct.description == args.account
            ]
        sync(ledger, accounts, args)
    else:
        _, file_extension = os.path.splitext(args.PATH)
        if file_extension == '.csv':
            import_csv(ledger, args)
        else:
            import_ofx(ledger, args)
Exemple #34
0
 def test_no_institution_no_fid(self):
     config = OfxConfig(os.path.join('fixtures', 'ofxclient.ini'))
     run([os.path.join('fixtures', 'no-institution.ofx'),
          '-l', os.path.join('fixtures', 'empty.lgr'),
          '-a', 'Assets:Savings:Foo'], config)
Exemple #35
0
def run(args=None, config=None):
    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Synchronize ledger.')
    parser.add_argument('-m', '--max', type=int, default=90,
                        help='maximum number of days to process')
    parser.add_argument('-r', '--resync', action='store_true', default=False,
                        help='do not stop until max days reached')
    parser.add_argument('PATH', nargs='?', help='do not sync; import from OFX \
file')
    parser.add_argument('-a', '--account', type=str, default=None,
                        help='sync only the named account; \
if importing from file, set account name for import')
    parser.add_argument('-l', '--ledger', type=str, default=None,
                        help='specify ledger file to READ for syncing')
    parser.add_argument(
        '-L',
        '--no-ledger',
        dest='no_ledger',
        action='store_true',
        default=False,
        help='do not de-duplicate against a ledger file')
    parser.add_argument('-i', '--indent', type=int, default=4,
                        help='number of spaces to use for indentation')
    parser.add_argument('--initial', action='store_true', default=False,
                        help='create initial balance entries')
    parser.add_argument('--fid', type=int, default=None,
                        help='pass in fid value for OFX files that do not \
supply it')
    parser.add_argument(
        '--hardcode-account',
        type=str,
        default=None,
        dest='hardcodeaccount',
        help='pass in hardcoded account number for OFX files \
to maintain ledger files without real account numbers')
    parser.add_argument(
        '--shorten-account',
        default=False,
        action='store_true',
        dest='shortenaccount',
        help='shorten all account numbers to last 4 digits \
to maintain ledger files without full account numbers')
    parser.add_argument('--unknown-account', type=str, dest='unknownaccount',
                        default=None,
                        help='specify account name to use when one can\'t be \
found by payee')
    parser.add_argument('--assertions', action='store_true', default=False,
                        help='create balance assertion entries')
    parser.add_argument('-d', '--debug', action='store_true', default=False,
                        help='enable debug logging')
    parser.add_argument('--hledger', action='store_true', default=False,
                        help='force use of hledger (on by default if invoked \
                        as hledger-autosync)')
    parser.add_argument(
        '--payee-format',
        type=str,
        default=None,
        dest='payee_format',
        help="""Format string to use for generating the payee line. Substitutions
        can be written using {memo}, {payee}, {txntype}, {account} or
        {tferaction} for OFX. If the input file is a CSV file,
        substitutions are written using the CSV file column names
        between {}.""")
    parser.add_argument('--python', action='store_true', default=False,
                        help='use the ledger python interface')
    parser.add_argument('--slow', action='store_true', default=False,
                        help='use slow, but possibly more robust, method of \
calling ledger (no subprocess)')
    parser.add_argument('--which', action='store_true', default=False,
                        help='display which version of ledger (cli), hledger, \
or ledger (python) will be used by ledger-autosync to check for previous \
transactions')
    parser.add_argument('--reverse', action='store_true', default=False,
                        help='print CSV transactions in reverse order')
    parser.add_argument('-o', '--ofxconfig', type=str, default=None,
                        help='specify config file for ofxclient')
    args = parser.parse_args(args)
    if sys.argv[0][-16:] == "hledger-autosync":
        args.hledger = True

    ledger_file = None
    if args.ledger and args.no_ledger:
        raise LedgerAutosyncException(
            'You cannot specify a ledger file and -L')
    elif args.ledger:
        ledger_file = args.ledger
    else:
        ledger_file = find_ledger_file()
    if args.debug:
        logging.basicConfig(level=logging.DEBUG)

    if ledger_file is None:
        sys.stderr.write("LEDGER_FILE environment variable not set, and no \
.ledgerrc file found, and -l argument was not supplied: running with deduplication disabled. \
All transactions will be printed!\n")
        ledger = None
    elif args.no_ledger:
        ledger = None
    elif args.hledger:
        ledger = HLedger(ledger_file)
    elif args.python:
        ledger = LedgerPython(ledger_file=ledger_file)
    elif args.slow:
        ledger = Ledger(ledger_file=ledger_file, no_pipe=True)
    else:
        ledger = mk_ledger(ledger_file)

    if args.which:
        sys.stderr.write("ledger-autosync is using ")
        if isinstance(ledger, Ledger):
            sys.stderr.write("ledger (cli)\n")
        elif isinstance(ledger, HLedger):
            sys.stderr.write("hledger\n")
        elif isinstance(ledger, LedgerPython):
            sys.stderr.write("ledger.so (python)\n")
        exit()

    config_dir = os.environ.get('XDG_CONFIG_HOME',
                                os.path.join(os.path.expanduser("~"),
                                             '.config'))

    load_plugins(config_dir)

    if args.PATH is None:
        if config is None:
            if args.ofxconfig is None:
                config_file = os.path.join(config_dir, 'ofxclient.ini')
            else:
                config_file = args.ofxconfig
            if (os.path.exists(config_file)):
                config = OfxConfig(file_name=config_file)
            else:
                config = OfxConfig()
        accounts = config.accounts()
        if args.account:
            accounts = [acct for acct in accounts
                        if acct.description == args.account]
        sync(ledger, accounts, args)
    else:
        _, file_extension = os.path.splitext(args.PATH.lower())
        if file_extension == '.csv':
            import_csv(ledger, args)
        else:
            import_ofx(ledger, args)
Exemple #36
0
def run(args=None, config=None):
    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Synchronize ledger.')
    parser.add_argument('-m',
                        '--max',
                        type=int,
                        default=90,
                        help='maximum number of days to process')
    parser.add_argument('-r',
                        '--resync',
                        action='store_true',
                        default=False,
                        help='do not stop until max days reached')
    parser.add_argument('PATH',
                        nargs='?',
                        help='do not sync; import from OFX \
file')
    parser.add_argument('-a',
                        '--account',
                        type=str,
                        default=None,
                        help='sync only the named account; \
if importing from file, set account name for import')
    parser.add_argument('-l',
                        '--ledger',
                        type=str,
                        default=None,
                        help='specify ledger file to READ for syncing')
    parser.add_argument('-L',
                        '--no-ledger',
                        dest='no_ledger',
                        action='store_true',
                        default=False,
                        help='do not de-duplicate against a ledger file')
    parser.add_argument('-i',
                        '--indent',
                        type=int,
                        default=4,
                        help='number of spaces to use for indentation')
    parser.add_argument('--initial',
                        action='store_true',
                        default=False,
                        help='create initial balance entries')
    parser.add_argument('--fid',
                        type=int,
                        default=None,
                        help='pass in fid value for OFX files that do not \
supply it')
    parser.add_argument('--hardcode-account',
                        type=str,
                        default=None,
                        dest='hardcodeaccount',
                        help='pass in hardcoded account number for OFX files \
to maintain ledger files without real account numbers')
    parser.add_argument('--shorten-account',
                        default=False,
                        action='store_true',
                        dest='shortenaccount',
                        help='shorten all account numbers to last 4 digits \
to maintain ledger files without full account numbers')
    parser.add_argument('--unknown-account',
                        type=str,
                        dest='unknownaccount',
                        default=None,
                        help='specify account name to use when one can\'t be \
found by payee')
    parser.add_argument('--assertions',
                        action='store_true',
                        default=False,
                        help='create balance assertion entries')
    parser.add_argument('-d',
                        '--debug',
                        action='store_true',
                        default=False,
                        help='enable debug logging')
    parser.add_argument('--hledger',
                        action='store_true',
                        default=False,
                        help='force use of hledger (on by default if invoked \
                        as hledger-autosync)')
    parser.add_argument(
        '--payee-format',
        type=str,
        default=None,
        dest='payee_format',
        help="""Format string to use for generating the payee line. Substitutions
        can be written using {memo}, {payee}, {txntype}, {account} or
        {tferaction} for OFX. If the input file is a CSV file,
        substitutions are written using the CSV file column names
        between {}.""")
    parser.add_argument('--python',
                        action='store_true',
                        default=False,
                        help='use the ledger python interface')
    parser.add_argument('--slow',
                        action='store_true',
                        default=False,
                        help='use slow, but possibly more robust, method of \
calling ledger (no subprocess)')
    parser.add_argument('--which',
                        action='store_true',
                        default=False,
                        help='display which version of ledger (cli), hledger, \
or ledger (python) will be used by ledger-autosync to check for previous \
transactions')
    parser.add_argument('--reverse',
                        action='store_true',
                        default=False,
                        help='print CSV transactions in reverse order')
    parser.add_argument('-o',
                        '--ofxconfig',
                        type=str,
                        default=None,
                        help='specify config file for ofxclient')
    parser.add_argument('-y',
                        '--date-format',
                        type=str,
                        default=None,
                        dest="date_format",
                        help="""Format string to use for printing dates.
                        See strftime for details on format string syntax. Default is "%%Y/%%m/%%d"."""
                        )
    parser.add_argument('--no-infer-account',
                        dest="infer_account",
                        action='store_false',
                        default=True,
                        help='disable inference of offset account from payee')
    args = parser.parse_args(args)
    if sys.argv[0][-16:] == "hledger-autosync":
        args.hledger = True

    ledger_file = None
    if args.ledger and args.no_ledger:
        raise LedgerAutosyncException(
            'You cannot specify a ledger file and -L')
    elif args.ledger:
        ledger_file = args.ledger
    else:
        ledger_file = find_ledger_file()
    if args.debug:
        logging.basicConfig(level=logging.DEBUG)

    if ledger_file is None:
        sys.stderr.write("LEDGER_FILE environment variable not set, and no \
.ledgerrc file found, and -l argument was not supplied: running with deduplication disabled. \
All transactions will be printed!\n")
        ledger = None
    elif args.no_ledger:
        ledger = None
    elif args.hledger:
        ledger = HLedger(ledger_file)
    elif args.python:
        ledger = LedgerPython(ledger_file=ledger_file)
    elif args.slow:
        ledger = Ledger(ledger_file=ledger_file, no_pipe=True)
    else:
        ledger = mk_ledger(ledger_file)

    if args.which:
        sys.stderr.write("ledger-autosync is using ")
        if isinstance(ledger, Ledger):
            sys.stderr.write("ledger (cli)\n")
        elif isinstance(ledger, HLedger):
            sys.stderr.write("hledger\n")
        elif isinstance(ledger, LedgerPython):
            sys.stderr.write("ledger.so (python)\n")
        exit()

    config_dir = os.environ.get(
        'XDG_CONFIG_HOME', os.path.join(os.path.expanduser("~"), '.config'))

    load_plugins(config_dir)

    if args.PATH is None:
        if config is None:
            if args.ofxconfig is None:
                config_file = os.path.join(config_dir, 'ofxclient.ini')
            else:
                config_file = args.ofxconfig
            if (os.path.exists(config_file)):
                config = OfxConfig(file_name=config_file)
            else:
                config = OfxConfig()
        accounts = config.accounts()
        if args.account:
            accounts = [
                acct for acct in accounts if acct.description == args.account
            ]
        sync(ledger, accounts, args)
    else:
        _, file_extension = os.path.splitext(args.PATH.lower())
        if file_extension == '.csv':
            import_csv(ledger, args)
        else:
            import_ofx(ledger, args)
Exemple #37
0
 def updateMenu(self):
     global GlobalConfig
     GlobalConfig = OfxConfig()
     self.statusitem.setMenu_(None)
     self.statusitem.setMenu_(self.makeMenu())