From 5116305866a268d65a513cb0d03a486a00a0c7ec Mon Sep 17 00:00:00 2001 From: Andrej Antunovikj Date: Mon, 29 Mar 2021 14:11:25 +0400 Subject: [PATCH 1/6] Added --format argument for `accounts [id] balance` --- nlbcli/__main__.py | 12 +++------ nlbcli/args_parser.py | 3 +++ nlbcli/formatter.py | 57 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 nlbcli/formatter.py diff --git a/nlbcli/__main__.py b/nlbcli/__main__.py index ed850b6..82bf1d8 100644 --- a/nlbcli/__main__.py +++ b/nlbcli/__main__.py @@ -4,6 +4,7 @@ import sys import os import re +from . import formatter from datetime import date, timedelta # local files @@ -41,15 +42,8 @@ def main(): url = 'https://www.nlbklik.com.mk/Retail/Account' _, soup = nlb_post(url, data) table_cells = soup.select('.dps-content') - print('Account Id:', parsed_args.account_id) - print('Account owner:', table_cells[0].text) - print('Status:', table_cells[1].text) - print('Current balance:', table_cells[3].text) - print('Available balance:', table_cells[5].text) - print('Allowed overdraft:', table_cells[7].text) - print('Reserved funds:', table_cells[9].text) - print('Last change:', table_cells[13].text) - print('Last interest:', table_cells[15].text) + # Print the data in the desired output format + formatter.OutputResult(parsed_args, table_cells) elif parsed_args.accounts_subparser_name == 'transactions': # direction explanation: diff --git a/nlbcli/args_parser.py b/nlbcli/args_parser.py index c0d3940..25e80f8 100644 --- a/nlbcli/args_parser.py +++ b/nlbcli/args_parser.py @@ -7,6 +7,8 @@ month_ago = today - timedelta(days=30) parser = argparse.ArgumentParser() +# FIXME: this would need to be enabled so that every command has the --format argument, instead of just nlbcli accounts balance +#parser.add_argument('--format', nargs="?", choices=['tab','csv','json'], required=False, default='tab') main_subparsers = parser.add_subparsers(dest='subparser_name') login_parser = main_subparsers.add_parser( 'login', help='Log in and save your credentials.') @@ -34,6 +36,7 @@ # ACCOUNTS [id] balance balance_parser = accounts_subparsers.add_parser( 'balance', help="Show the balance on the specified account") +balance_parser.add_argument('--format', nargs="?", choices=['tab','csv','json'], required=False, default='tab') # ACCOUNtS [id] reservations reservations_parser = accounts_subparsers.add_parser( diff --git a/nlbcli/formatter.py b/nlbcli/formatter.py new file mode 100644 index 0000000..d78e125 --- /dev/null +++ b/nlbcli/formatter.py @@ -0,0 +1,57 @@ +import re +import csv +import json +import sys + + +def OutputResult(parsed_args, table_cells): + # print(parsed_args) + output_format = parsed_args.format + if output_format == 'tab': + print('Account Id:', parsed_args.account_id) + print('Account owner:', table_cells[0].text) + print('Status:', table_cells[1].text) + print('Current balance:', table_cells[3].text) + print('Available balance:', table_cells[5].text) + print('Allowed overdraft:', table_cells[7].text) + print('Reserved funds:', table_cells[9].text) + print('Last change:', table_cells[13].text) + print('Last interest:', table_cells[15].text) + elif output_format == 'json': + json_output = json.dumps( + { + 'account-id': parsed_args.account_id, + 'account-owner': table_cells[0].text, + 'account-status': table_cells[1].text, + 'current-balance': table_cells[3].text, + 'available-balance': table_cells[5].text, + 'allowed-overdraft': table_cells[7].text, + 'reserved-funds': table_cells[9].text, + 'last-change': table_cells[13].text, + 'last-interest': table_cells[15].text + } + ) + print(json_output) + elif output_format == 'csv': + field_names = ['account-id', + 'account-owner', + 'account-status', + 'current-balance', + 'available-balance', + 'allowed-overdraft', + 'reserved-funds', + 'last-change', + 'last-interest'] + csv_writer = csv.DictWriter(sys.stdout, field_names) + csv_writer.writeheader() + csv_writer.writerow({ + 'account-id': parsed_args.account_id, + 'account-owner': table_cells[0].text, + 'account-status': table_cells[1].text, + 'current-balance': table_cells[3].text, + 'available-balance': table_cells[5].text, + 'allowed-overdraft': table_cells[7].text, + 'reserved-funds': table_cells[9].text, + 'last-change': table_cells[13].text, + 'last-interest': table_cells[15].text + }) From e6758d6f4556fb2938d2cefa6f5772c7aee018b6 Mon Sep 17 00:00:00 2001 From: Andrej Antunovikj Date: Fri, 29 Oct 2021 10:10:03 -0400 Subject: [PATCH 2/6] Remove debug statement --- nlbcli/formatter.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/nlbcli/formatter.py b/nlbcli/formatter.py index d78e125..b7bec4e 100644 --- a/nlbcli/formatter.py +++ b/nlbcli/formatter.py @@ -5,7 +5,6 @@ def OutputResult(parsed_args, table_cells): - # print(parsed_args) output_format = parsed_args.format if output_format == 'tab': print('Account Id:', parsed_args.account_id) @@ -45,13 +44,13 @@ def OutputResult(parsed_args, table_cells): csv_writer = csv.DictWriter(sys.stdout, field_names) csv_writer.writeheader() csv_writer.writerow({ - 'account-id': parsed_args.account_id, - 'account-owner': table_cells[0].text, - 'account-status': table_cells[1].text, - 'current-balance': table_cells[3].text, - 'available-balance': table_cells[5].text, - 'allowed-overdraft': table_cells[7].text, - 'reserved-funds': table_cells[9].text, - 'last-change': table_cells[13].text, - 'last-interest': table_cells[15].text - }) + 'account-id': parsed_args.account_id, + 'account-owner': table_cells[0].text, + 'account-status': table_cells[1].text, + 'current-balance': table_cells[3].text, + 'available-balance': table_cells[5].text, + 'allowed-overdraft': table_cells[7].text, + 'reserved-funds': table_cells[9].text, + 'last-change': table_cells[13].text, + 'last-interest': table_cells[15].text + }) From e35cbe483d5eaff60fee4047322c0583657da70a Mon Sep 17 00:00:00 2001 From: Andrej Antunovikj Date: Tue, 4 Oct 2022 08:48:37 -0400 Subject: [PATCH 3/6] Enhancements to the formatter, pretty-print JSON --- nlbcli/__main__.py | 6 +-- nlbcli/args_parser.py | 1 + nlbcli/formatter.py | 97 ++++++++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/nlbcli/__main__.py b/nlbcli/__main__.py index 82bf1d8..f0f09ff 100644 --- a/nlbcli/__main__.py +++ b/nlbcli/__main__.py @@ -43,7 +43,7 @@ def main(): _, soup = nlb_post(url, data) table_cells = soup.select('.dps-content') # Print the data in the desired output format - formatter.OutputResult(parsed_args, table_cells) + formatter.OutputResult(parsed_args, table_cells, "accounts") elif parsed_args.accounts_subparser_name == 'transactions': # direction explanation: @@ -89,9 +89,7 @@ def main(): # we print all cells except the "Details" link/button # todo: parse the 0th column to extract the unique transaction id - for tr in soup.select('tbody > tr'): - tds = tr.select('td')[1:] - print('\t'.join(td.text.strip() for td in tds)) + formatter.OutputResult(parsed_args, soup.select('tbody > tr'), "transactions") elif parsed_args.accounts_subparser_name == 'reservations': url = 'https://www.nlbklik.com.mk/Retail/ReservationList' diff --git a/nlbcli/args_parser.py b/nlbcli/args_parser.py index 25e80f8..4855ca8 100644 --- a/nlbcli/args_parser.py +++ b/nlbcli/args_parser.py @@ -32,6 +32,7 @@ transactions_parser.add_argument( '--type', choices=['in', 'out'], required=False) transactions_parser.add_argument('--name', required=False) +transactions_parser.add_argument('--format', nargs="?", choices=['tab','csv','json'], required=False, default='tab') # ACCOUNTS [id] balance balance_parser = accounts_subparsers.add_parser( diff --git a/nlbcli/formatter.py b/nlbcli/formatter.py index b7bec4e..ca8e2a8 100644 --- a/nlbcli/formatter.py +++ b/nlbcli/formatter.py @@ -4,21 +4,67 @@ import sys -def OutputResult(parsed_args, table_cells): +def OutputResult(parsed_args, table_cells, input_type): output_format = parsed_args.format if output_format == 'tab': - print('Account Id:', parsed_args.account_id) - print('Account owner:', table_cells[0].text) - print('Status:', table_cells[1].text) - print('Current balance:', table_cells[3].text) - print('Available balance:', table_cells[5].text) - print('Allowed overdraft:', table_cells[7].text) - print('Reserved funds:', table_cells[9].text) - print('Last change:', table_cells[13].text) - print('Last interest:', table_cells[15].text) + if input_type == "accounts": + print('Account Id:', parsed_args.account_id) + print('Account owner:', table_cells[0].text) + print('Status:', table_cells[1].text) + print('Current balance:', table_cells[3].text) + print('Available balance:', table_cells[5].text) + print('Allowed overdraft:', table_cells[7].text) + print('Reserved funds:', table_cells[9].text) + print('Last change:', table_cells[13].text) + print('Last interest:', table_cells[15].text) + elif input_type == "transactions": + for tr in table_cells: + tds = tr.select('td')[1:] + print('\t'.join(td.text.strip() for td in tds)) elif output_format == 'json': - json_output = json.dumps( - { + if input_type == "accounts": + json_output = json.dumps( + { + 'account-id': parsed_args.account_id, + 'account-owner': table_cells[0].text, + 'account-status': table_cells[1].text, + 'current-balance': table_cells[3].text, + 'available-balance': table_cells[5].text, + 'allowed-overdraft': table_cells[7].text, + 'reserved-funds': table_cells[9].text, + 'last-change': table_cells[13].text, + 'last-interest': table_cells[15].text + },indent=4 + ) + elif input_type == "transactions": + txns = [] + for tr in table_cells: + tds = tr.select('td')[1:] + dict_txn = {} + dict_txn['date'] = tds[0].text.strip() + dict_txn['recipient_name'] = tds[1].text.strip() + dict_txn['txn_description'] = tds[2].text.strip() + dict_txn['status'] = tds[3].text.strip() + dict_txn['amount'] = tds[4].text.strip() + dict_txn['txn_fee'] = tds[5].text.strip() + dict_txn['balance'] = tds[6].text.strip() + txns.append(dict_txn) + json_output = json.dumps(txns,indent=4) + print(json_output) + elif output_format == 'csv': + if input_type == "accounts": + field_names = ['account-id', + 'account-owner', + 'account-status', + 'current-balance', + 'available-balance', + 'allowed-overdraft', + 'reserved-funds', + 'last-change', + 'last-interest'] + csv_writer = csv.DictWriter(sys.stdout, field_names) + csv_writer.writeheader() + csv_writer.writerow({ 'account-id': parsed_args.account_id, 'account-owner': table_cells[0].text, 'account-status': table_cells[1].text, @@ -28,29 +74,4 @@ def OutputResult(parsed_args, table_cells): 'reserved-funds': table_cells[9].text, 'last-change': table_cells[13].text, 'last-interest': table_cells[15].text - } - ) - print(json_output) - elif output_format == 'csv': - field_names = ['account-id', - 'account-owner', - 'account-status', - 'current-balance', - 'available-balance', - 'allowed-overdraft', - 'reserved-funds', - 'last-change', - 'last-interest'] - csv_writer = csv.DictWriter(sys.stdout, field_names) - csv_writer.writeheader() - csv_writer.writerow({ - 'account-id': parsed_args.account_id, - 'account-owner': table_cells[0].text, - 'account-status': table_cells[1].text, - 'current-balance': table_cells[3].text, - 'available-balance': table_cells[5].text, - 'allowed-overdraft': table_cells[7].text, - 'reserved-funds': table_cells[9].text, - 'last-change': table_cells[13].text, - 'last-interest': table_cells[15].text - }) + }) From c960df28910cd60fe610ac3d2cf2410bbe09f71c Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Wed, 28 Feb 2024 23:09:45 +0100 Subject: [PATCH 4/6] Handle the accounts->transactions output format to csv case. --- nlbcli/formatter.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nlbcli/formatter.py b/nlbcli/formatter.py index ca8e2a8..06c6162 100644 --- a/nlbcli/formatter.py +++ b/nlbcli/formatter.py @@ -75,3 +75,24 @@ def OutputResult(parsed_args, table_cells, input_type): 'last-change': table_cells[13].text, 'last-interest': table_cells[15].text }) + elif input_type == "transactions": + field_names = ['date', + 'recipient_name', + 'txn_description', + 'status', + 'amount', + 'txn_fee', + 'balance'] + csv_writer = csv.DictWriter(sys.stdout, field_names) + csv_writer.writeheader() + for tr in table_cells: + tds = tr.select('td')[1:] + csv_writer.writerow({ + 'date': tds[0].text.strip(), + 'recipient_name': tds[1].text.strip(), + 'txn_description': tds[2].text.strip(), + 'status': tds[3].text.strip(), + 'amount': tds[4].text.strip(), + 'txn_fee': tds[5].text.strip(), + 'balance': tds[6].text.strip(), + }) From 4c1b336d42d1e206be49554c92dbb3a7c553b8c1 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Sun, 29 Sep 2024 13:06:41 +0200 Subject: [PATCH 5/6] Set the page size to 100. --- nlbcli/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nlbcli/__main__.py b/nlbcli/__main__.py index f0f09ff..e8544c6 100644 --- a/nlbcli/__main__.py +++ b/nlbcli/__main__.py @@ -64,7 +64,7 @@ def main(): "SaveFilter": "False", "RemoveFilter": "False", "PageNumber": "", - "PageSize": "", + "PageSize": "100", "DetailsView": "0", "SelectedItem": "", "PageId": "", From 8feab233a43edd2c4f753b652ad92b2c2aa7b2d7 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Sun, 29 Sep 2024 14:26:04 +0200 Subject: [PATCH 6/6] Add setuptools as install deps. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index e1df798..da3bc57 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ 'console_scripts': ['nlbcli=nlbcli.__main__:main'] }, install_requires=[ + 'setuptools', 'requests>=2.25.0', 'beautifulsoup4>=4.9.3' ],