From d03e6307f5e8c0b1c0451636ac9b1e84f3529a73 Mon Sep 17 00:00:00 2001 From: tobi-wan-kenobi Date: Fri, 21 Jul 2023 14:18:17 +0200 Subject: [PATCH] [contrib/stock] change API to alphavantage.co Changed the stock module to work again (with an API key), and make it easier to change the data provider by the user. fixes #971 --- bumblebee_status/modules/contrib/stock.py | 60 +++++++++++++---------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/bumblebee_status/modules/contrib/stock.py b/bumblebee_status/modules/contrib/stock.py index 224a5fb8..6b35bf7d 100644 --- a/bumblebee_status/modules/contrib/stock.py +++ b/bumblebee_status/modules/contrib/stock.py @@ -5,7 +5,9 @@ Parameters: * stock.symbols : Comma-separated list of symbols to fetch - * stock.change : Should we fetch change in stock value (defaults to True) + * stock.apikey : API key created on https://alphavantage.co + * stock.url : URL to use, defaults to "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={symbol}&apikey={apikey}" + * stock.fields : Fields from the response to show, defaults to "01. symbol,05. price,10. change percent" contributed by `msoulier `_ - many thanks! @@ -22,6 +24,12 @@ import util.format +def flatten(d, result): + for k, v in d.items(): + if type(v) is dict: + flatten(v, result) + else: + result[k] = v class Module(core.module.Module): @core.decorators.every(hours=1) @@ -29,41 +37,41 @@ def __init__(self, config, theme): super().__init__(config, theme, core.widget.Widget(self.value)) self.__symbols = self.parameter("symbols", "") + self.__apikey = self.parameter("apikey", None) + self.__fields = self.parameter("fields", "01. symbol,05. price,10. change percent").split(",") + self.__url = self.parameter("url", "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={symbol}&apikey={apikey}") self.__change = util.format.asbool(self.parameter("change", True)) - self.__value = None + self.__values = [] + def value(self, widget): - results = [] - if not self.__value: - return "n/a" - data = json.loads(self.__value) - - for symbol in data["quoteResponse"]["result"]: - valkey = "regularMarketChange" if self.__change else "regularMarketPrice" - sym = symbol.get("symbol", "n/a") - currency = symbol.get("currency", "USD") - val = "n/a" if not valkey in symbol else "{:.2f}".format(symbol[valkey]) - results.append("{} {} {}".format(sym, val, currency)) - return " ".join(results) + result = "" + + for value in self.__values: + res = {} + flatten(value, res) + for field in self.__fields: + result += res.get(field, "n/a") + " " + result = result[:-1] + return result def fetch(self): + results = [] if self.__symbols: - url = "https://query1.finance.yahoo.com/v7/finance/quote?symbols=" - url += ( - self.__symbols - + "&fields=regularMarketPrice,currency,regularMarketChange" - ) - try: - return urllib.request.urlopen(url).read().strip() - except urllib.request.URLError: - logging.error("unable to open stock exchange url") - return None + for symbol in self.__symbols.split(","): + url = self.__url.format(symbol=symbol, apikey=self.__apikey) + try: + results.append(json.loads(urllib.request.urlopen(url).read().strip())) + except urllib.request.URLError: + logging.error("unable to open stock exchange url") + return [] else: logging.error("unable to retrieve stock exchange rate") - return None + return [] + return results def update(self): - self.__value = self.fetch() + self.__values = self.fetch() # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4