From 0b2b076d61500f0aa2b29944c70dde759795f26e Mon Sep 17 00:00:00 2001 From: Chris Berkhout Date: Tue, 4 May 2021 17:58:16 +0200 Subject: [PATCH] Add --symbols option, implement for ECB. --- src/pricehist/cli.py | 34 +++++++++++------ src/pricehist/sources/ecb.py | 71 +++++++++--------------------------- 2 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/pricehist/cli.py b/src/pricehist/cli.py index b0cdcfe..0195edd 100644 --- a/src/pricehist/cli.py +++ b/src/pricehist/cli.py @@ -50,20 +50,23 @@ def cmd_source(args): first_output = wrapper.wrap(first) wrapper.initial_indent = subsequent_indent rest_output = sum([wrapper.wrap(line) for line in rest], []) - # TODO use str.splitlines()? - print("\n".join(first_output + rest_output)) + output = "\n".join(first_output + rest_output) + if output != "": + print(output) - source = sources.by_id[args.identifier] - key_width = 11 - output_width = shutil.get_terminal_size().columns + source = sources.by_id[args.identifier]() - print_field("ID", source.id(), key_width, output_width) - print_field("Name", source.name(), key_width, output_width) - print_field("Description", source.description(), key_width, output_width) - print_field("URL", source.source_url(), key_width, output_width, force=False) - print_field("Notes", source.notes(), key_width, output_width) - print_field("Bases", ", ".join(source.bases()), key_width, output_width) - print_field("Quotes", ", ".join(source.quotes()), key_width, output_width) + if args.symbols: + print("\n".join(source.symbols())) + else: + key_width = 11 + output_width = shutil.get_terminal_size().columns + + print_field("ID", source.id(), key_width, output_width) + print_field("Name", source.name(), key_width, output_width) + print_field("Description", source.description(), key_width, output_width) + print_field("URL", source.source_url(), key_width, output_width, force=False) + print_field("Notes", source.notes(), key_width, output_width) def cmd_fetch(args): @@ -157,6 +160,7 @@ def build_parser(): source_parser = subparsers.add_parser( "source", help="show source details", + usage="pricehist source SOURCE [-h] [-s]", formatter_class=formatter, ) source_parser.add_argument( @@ -166,6 +170,12 @@ def build_parser(): choices=sources.by_id.keys(), help="the source identifier", ) + source_parser.add_argument( + "-s", + "--symbols", + action="store_true", + help="list available symbols", + ) fetch_parser = subparsers.add_parser( "fetch", diff --git a/src/pricehist/sources/ecb.py b/src/pricehist/sources/ecb.py index 0e6a668..0c6bf3a 100644 --- a/src/pricehist/sources/ecb.py +++ b/src/pricehist/sources/ecb.py @@ -28,68 +28,23 @@ class ECB: def notes(): return "" - @staticmethod - def bases(): - return ["EUR"] - - @staticmethod - def quotes(): - return [ - "AUD", - "BGN", - "BRL", - "CAD", - "CHF", - "CNY", - "CZK", - "DKK", - "GBP", - "HKD", - "HRK", - "HUF", - "IDR", - "ILS", - "INR", - "ISK", - "JPY", - "KRW", - "MXN", - "MYR", - "NOK", - "NZD", - "PHP", - "PLN", - "RON", - "RUB", - "SEK", - "SGD", - "THB", - "TRY", - "USD", - "ZAR", - ] + def symbols(self): + data = self._raw_data(more_than_90_days=True) + root = etree.fromstring(data) + nodes = root.cssselect("[currency]") + currencies = sorted(set([n.attrib["currency"] for n in nodes])) + pairs = [f"EUR/{c}" for c in currencies] + return pairs def fetch(self, pair, type, start, end): base, quote = pair.split("/") - if base not in self.bases(): - exit(f"Invalid base {base}") - if quote not in self.quotes(): - exit(f"Invalid quote {quote}") min_start = "1999-01-04" if start < min_start: exit(f"start {start} too early. Minimum is {min_start}") almost_90_days_ago = str(datetime.now().date() - timedelta(days=85)) - url_base = "https://www.ecb.europa.eu/stats/eurofxref" - if start > almost_90_days_ago: - source_url = f"{url_base}/eurofxref-hist-90d.xml" # last 90 days - else: - source_url = f"{url_base}/eurofxref-hist.xml" # since 1999 - - response = requests.get(source_url) - data = response.content - + data = self._raw_data(start > almost_90_days_ago) root = etree.fromstring(data) all_rows = [] @@ -105,3 +60,13 @@ class ECB: ] return selected + + def _raw_data(self, more_than_90_days=False): + url_base = "https://www.ecb.europa.eu/stats/eurofxref" + if more_than_90_days: + source_url = f"{url_base}/eurofxref-hist.xml" # since 1999 + else: + source_url = f"{url_base}/eurofxref-hist-90d.xml" # last 90 days + + response = requests.get(source_url) + return response.content