Add --format-decimal --format-thousands --format-symbol and --format-datesep.
This commit is contained in:
parent
be039d7ad8
commit
ec7df02391
6 changed files with 105 additions and 13 deletions
|
@ -3,6 +3,7 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
from pricehist import outputs, sources
|
from pricehist import outputs, sources
|
||||||
from pricehist import __version__
|
from pricehist import __version__
|
||||||
|
from pricehist.formatinfo import FormatInfo
|
||||||
|
|
||||||
|
|
||||||
def cli(args=None):
|
def cli(args=None):
|
||||||
|
@ -61,8 +62,17 @@ def cmd_fetch(args):
|
||||||
for p in prices
|
for p in prices
|
||||||
]
|
]
|
||||||
|
|
||||||
time = args.renametime or "00:00:00"
|
default = FormatInfo()
|
||||||
print(output.format(prices, time=time), end="")
|
|
||||||
|
fi = FormatInfo(
|
||||||
|
time=(args.renametime or default.time),
|
||||||
|
decimal=(args.formatdecimal or default.decimal),
|
||||||
|
thousands=(args.formatthousands or default.thousands),
|
||||||
|
symbol=(args.formatsymbol or default.symbol),
|
||||||
|
datesep=(args.formatdatesep or default.datesep),
|
||||||
|
)
|
||||||
|
|
||||||
|
print(output.format(prices, format_info=fi), end="")
|
||||||
|
|
||||||
|
|
||||||
def build_parser():
|
def build_parser():
|
||||||
|
@ -190,5 +200,34 @@ def build_parser():
|
||||||
type=str,
|
type=str,
|
||||||
help="set a particular time of day, e.g. 23:59:59",
|
help="set a particular time of day, e.g. 23:59:59",
|
||||||
)
|
)
|
||||||
|
fetch_parser.add_argument(
|
||||||
|
"--format-decimal",
|
||||||
|
dest="formatdecimal",
|
||||||
|
metavar="CHAR",
|
||||||
|
type=str,
|
||||||
|
help="decimal point",
|
||||||
|
)
|
||||||
|
fetch_parser.add_argument(
|
||||||
|
"--format-thousands",
|
||||||
|
dest="formatthousands",
|
||||||
|
metavar="CHAR",
|
||||||
|
type=str,
|
||||||
|
help="thousands separator",
|
||||||
|
)
|
||||||
|
fetch_parser.add_argument(
|
||||||
|
"--format-symbol",
|
||||||
|
dest="formatsymbol",
|
||||||
|
metavar="CHAR",
|
||||||
|
type=str,
|
||||||
|
choices=["rightspace", "right", "leftspace", "left"],
|
||||||
|
help="placement of the quote's commodity symbol relative to its amount",
|
||||||
|
)
|
||||||
|
fetch_parser.add_argument(
|
||||||
|
"--format-datesep",
|
||||||
|
dest="formatdatesep",
|
||||||
|
metavar="CHAR",
|
||||||
|
type=str,
|
||||||
|
help="date separator",
|
||||||
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
7
src/pricehist/formatinfo.py
Normal file
7
src/pricehist/formatinfo.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
FormatInfo = namedtuple(
|
||||||
|
"FormatInfo",
|
||||||
|
["time", "decimal", "thousands", "symbol", "datesep"],
|
||||||
|
defaults=["00:00:00", ".", "", "rightspace", "-"],
|
||||||
|
)
|
|
@ -1,13 +1,30 @@
|
||||||
|
from pricehist.formatinfo import FormatInfo
|
||||||
|
|
||||||
|
|
||||||
class Beancount:
|
class Beancount:
|
||||||
def format(self, prices, time=None):
|
def format(self, prices, format_info=FormatInfo()):
|
||||||
lines = []
|
lines = []
|
||||||
for price in prices:
|
for price in prices:
|
||||||
lines.append(
|
|
||||||
f"{price.date} price {price.base} {price.amount} {price.quote}"
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
)
|
amount_parts[0] = amount_parts[0].replace(",", format_info.thousands)
|
||||||
|
amount = ".".join(amount_parts)
|
||||||
|
|
||||||
|
qa_parts = [amount]
|
||||||
|
if format_info.symbol == "right":
|
||||||
|
qa_parts = qa_parts + [price.quote]
|
||||||
|
else:
|
||||||
|
qa_parts = qa_parts + [" ", price.quote]
|
||||||
|
quote_amount = "".join(qa_parts)
|
||||||
|
|
||||||
|
date = str(price.date).replace("-", format_info.datesep)
|
||||||
|
lines.append(f"{date} price {price.base} {quote_amount}")
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: Beancount always has commodity to the right. It seems to be possible to
|
||||||
|
# skip the space, according to https://plaintextaccounting.org/quickref/#h.n4b87oz9ku6t
|
||||||
|
|
||||||
# https://beancount.github.io/docs/fetching_prices_in_beancount.html
|
# https://beancount.github.io/docs/fetching_prices_in_beancount.html
|
||||||
# https://beancount.github.io/docs/beancount_language_syntax.html#commodities-currencies
|
# https://beancount.github.io/docs/beancount_language_syntax.html#commodities-currencies
|
||||||
# https://beancount.github.io/docs/beancount_language_syntax.html#comments
|
# https://beancount.github.io/docs/beancount_language_syntax.html#comments
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
|
from pricehist.formatinfo import FormatInfo
|
||||||
|
|
||||||
|
|
||||||
class CSV:
|
class CSV:
|
||||||
def format(self, prices, time=None):
|
def format(self, prices, format_info=FormatInfo()):
|
||||||
lines = ["date,base,quote,amount"]
|
lines = ["date,base,quote,amount"]
|
||||||
for price in prices:
|
for price in prices:
|
||||||
line = ",".join([price.date, price.base, price.quote, str(price.amount)])
|
date = str(price.date).replace("-", format_info.datesep)
|
||||||
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
|
amount_parts[0] = amount_parts[0].replace(",", format_info.thousands)
|
||||||
|
amount = format_info.decimal.join(amount_parts)
|
||||||
|
line = ",".join([date, price.base, price.quote, amount])
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
|
@ -3,16 +3,18 @@ from datetime import datetime
|
||||||
from importlib.resources import read_text
|
from importlib.resources import read_text
|
||||||
|
|
||||||
from pricehist import __version__
|
from pricehist import __version__
|
||||||
|
from pricehist.formatinfo import FormatInfo
|
||||||
|
|
||||||
|
|
||||||
class GnuCashSQL:
|
class GnuCashSQL:
|
||||||
def format(self, prices, time=None):
|
def format(self, prices, format_info=FormatInfo()):
|
||||||
|
fi = format_info
|
||||||
source = "pricehist"
|
source = "pricehist"
|
||||||
typ = "unknown"
|
typ = "unknown"
|
||||||
|
|
||||||
values_parts = []
|
values_parts = []
|
||||||
for price in prices:
|
for price in prices:
|
||||||
date = f"{price.date} {time}"
|
date = f"{price.date} {fi.time}"
|
||||||
m = hashlib.sha256()
|
m = hashlib.sha256()
|
||||||
m.update(
|
m.update(
|
||||||
"".join(
|
"".join(
|
||||||
|
|
|
@ -1,9 +1,29 @@
|
||||||
|
from pricehist.formatinfo import FormatInfo
|
||||||
|
|
||||||
|
|
||||||
class Ledger:
|
class Ledger:
|
||||||
def format(self, prices, time=None):
|
def format(self, prices, format_info=FormatInfo()):
|
||||||
|
fi = format_info
|
||||||
lines = []
|
lines = []
|
||||||
for price in prices:
|
for price in prices:
|
||||||
date = str(price.date).translate(str.maketrans("-", "/"))
|
date = str(price.date).replace("-", fi.datesep)
|
||||||
lines.append(f"P {date} {time} {price.base} {price.amount} {price.quote}")
|
|
||||||
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
|
amount_parts[0] = amount_parts[0].replace(",", format_info.thousands)
|
||||||
|
amount = format_info.decimal.join(amount_parts)
|
||||||
|
|
||||||
|
qa_parts = [amount]
|
||||||
|
if format_info.symbol == "left":
|
||||||
|
qa_parts = [price.quote] + qa_parts
|
||||||
|
elif format_info.symbol == "leftspace":
|
||||||
|
qa_parts = [price.quote, " "] + qa_parts
|
||||||
|
elif format_info.symbol == "right":
|
||||||
|
qa_parts = qa_parts + [price.quote]
|
||||||
|
else:
|
||||||
|
qa_parts = qa_parts + [" ", price.quote]
|
||||||
|
quote_amount = "".join(qa_parts)
|
||||||
|
|
||||||
|
lines.append(f"P {date} {fi.time} {price.base} {quote_amount}")
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
# TODO support additional details of the format:
|
# TODO support additional details of the format:
|
||||||
|
|
Loading…
Add table
Reference in a new issue