Generate CSV with the correct escaping.

This commit is contained in:
Chris Berkhout 2021-05-29 22:12:36 +02:00
parent 2c3805e4b0
commit 249d426f9f
3 changed files with 41 additions and 8 deletions

View file

@ -97,6 +97,13 @@ def build_parser():
def today():
return datetime.now().date().isoformat()
def valid_char(s):
if len(s) == 1:
return s
else:
msg = f"Not a single character: '{s}'."
raise argparse.ArgumentTypeError(msg)
def formatter(prog):
return argparse.HelpFormatter(prog, max_help_position=50)
@ -165,6 +172,7 @@ def build_parser():
"[--fmt-base SYM] [--fmt-quote SYM] [--fmt-time TIME] "
"[--fmt-decimal CHAR] [--fmt-thousands CHAR] "
"[--fmt-symbol rightspace|right|leftspace|left] [--fmt-datesep CHAR] "
"[--fmt-csvdelim CHAR]"
),
formatter_class=formatter,
)
@ -299,5 +307,12 @@ def build_parser():
type=str,
help=f"date separator in output (default: '{default_fmt.datesep}')",
)
fetch_parser.add_argument(
"--fmt-csvdelim",
dest="formatcsvdelim",
metavar="CHAR",
type=valid_char,
help=f"field delimiter for CSV output (default: '{default_fmt.csvdelim}')",
)
return parser

View file

@ -10,6 +10,7 @@ class Format:
thousands: str = ""
symbol: str = "rightspace"
datesep: str = "-"
csvdelim: str = ","
@classmethod
def fromargs(cls, args):
@ -25,6 +26,7 @@ class Format:
thousands=if_not_none(args.formatthousands, default.thousands),
symbol=if_not_none(args.formatsymbol, default.symbol),
datesep=if_not_none(args.formatdatesep, default.datesep),
csvdelim=if_not_none(args.formatcsvdelim, default.csvdelim),
)
def format_date(self, date):

View file

@ -1,16 +1,32 @@
from pricehist.format import Format
import csv
import io
from pricehist.format import Format
from .baseoutput import BaseOutput
class CSV(BaseOutput):
def format(self, series, source=None, fmt=Format()):
lines = ["date,base,quote,amount,source,type"]
for price in series.prices:
date = fmt.format_date(price.date)
output = io.StringIO()
writer = csv.writer(
output,
delimiter=fmt.csvdelim,
lineterminator="\n",
quotechar='"',
doublequote=True,
skipinitialspace=False,
quoting=csv.QUOTE_MINIMAL,
)
header = ["date", "base", "quote", "amount", "source", "type"]
writer.writerow(header)
base = fmt.base or series.base
quote = fmt.quote or series.quote
for price in series.prices:
date = fmt.format_date(price.date)
amount = fmt.format_num(price.amount)
line = ",".join([date, base, quote, amount, source.id(), series.type])
lines.append(line)
return "\n".join(lines) + "\n"
writer.writerow([date, base, quote, amount, source.id(), series.type])
return output.getvalue()