Skip to content

Commit

Permalink
Add --json option for list command to return JSON data
Browse files Browse the repository at this point in the history
Close #120
  • Loading branch information
pylipp committed Jan 3, 2023
1 parent ed846f8 commit 0ec5e7f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Removed
### Deprecated

## [v1.2.0] - 2023-01-
### Added
- New `--json` option for `list` command to return result in JSON format instead of formatted as table (#120). Helpful for processing data with jq or similar tools (refine selection with `--filter` option):
- all IDs of standard entries: `fina list --json | jq -r '.standard | keys[]'`
- all IDs of recurrent entries: `fina list --json | jq -r '.standard | keys[]'`
- all IDs of recurrent entries: `fina list --json --recurrent-only | jq .[].eid`

## [v1.1.6] - 2023-01-02
### Changed
- Update dependencies `rich` and `marshmallow`. (#140,#142)
Expand Down
8 changes: 8 additions & 0 deletions financeager/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def _info(message):
"entry_sort",
"category_sort",
"category_percentage",
"json",
]:
formatting_options[option] = params.pop(option)
if params["recurrent_only"]:
Expand Down Expand Up @@ -446,6 +447,13 @@ def _parse_command(args=None, plugins=None):
action="store_true",
help="show only recurrent entries",
)
list_parser.add_argument(
"-j",
"--json",
action="store_true",
help="return result in JSON format instead formatting into table. "
"Helpful for processing data with jq or similar tools.",
)

subparsers.add_parser("pockets", help="list all pocket databases")

Expand Down
6 changes: 6 additions & 0 deletions financeager/listing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Tabular, frontend-representation of financeager pocket."""
from json import dumps as jdumps

from . import DEFAULT_TABLE, RECURRENT_TABLE
from .entries import BaseEntry, CategoryEntry
from .rich import richify_listings, richify_recurrent_elements
Expand Down Expand Up @@ -85,16 +87,20 @@ def total_value(self):
def prettify(
elements,
recurrent_only=False,
json=False,
default_category=None,
**listing_options,
):
"""Sort the given elements (type acc. to Pocket._search_all_tables) by
positive and negative value and print tabular representation.
:param json: If True, return elements as JSON-formatted string
:param recurrent_only: If True, assume that given elements are purely
recurrent ones
:param listing_options: Options passed to rich.richify_listings()
"""
if json:
return jdumps(elements)

if recurrent_only:
entry_sort = listing_options.get("entry_sort")
Expand Down
25 changes: 24 additions & 1 deletion test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import unittest
from collections import defaultdict
from datetime import datetime as dt
from json import loads as jloads
from unittest import mock

from rich.table import Table as RichTable
Expand Down Expand Up @@ -97,7 +98,9 @@ def cli_run(self, command_line, log_method="info", format_args=()):
if command in ["add", "update", "remove", "copy"]:
return response["id"]

if command in ["get", "pockets"] and log_method == "info":
if (command in ["get", "pockets"] and log_method == "info") or (
command == "list" and log_method == "info" and params.get("json")
):
return cli._format_response(
response,
command,
Expand All @@ -106,6 +109,7 @@ def cli_run(self, command_line, log_method="info", format_args=()):
),
recurrent_only=params.get("recurrent_only", False),
entry_sort=params.get("entry_sort"),
json=params.get("json"),
)

if command == "list" and log_method == "info":
Expand Down Expand Up @@ -357,6 +361,25 @@ def test_list_recurrent_only(self):
},
)

def test_list_json(self):
entry_id = self.cli_run("add money 10")
response = self.cli_run("list --json")
today = dt.today().strftime("%Y-%m-%d")
self.assertEqual(
jloads(response),
{
DEFAULT_TABLE: {
str(entry_id): {
"category": None,
"date": today,
"name": "money",
"value": 10.0,
}
},
RECURRENT_TABLE: {},
},
)

@mock.patch("financeager.server.Server.run")
def test_communication_error(self, mocked_run):
# Raise exception on first call, behave fine on stop call
Expand Down

0 comments on commit 0ec5e7f

Please sign in to comment.