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') )
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
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)
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)
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)
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!')
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')
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" )
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()
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()
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() )
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') )
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()
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())
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)
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)
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 )
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)
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)
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()
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)
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)
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)