From 18bde7391efb9c6bd6ea7846891ab5d16276a809 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Mon, 31 May 2021 06:11:22 -0700 Subject: initial import A bit messy and missing error handling in some places. --- yahoo.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 yahoo.c (limited to 'yahoo.c') diff --git a/yahoo.c b/yahoo.c new file mode 100644 index 0000000..7b54922 --- /dev/null +++ b/yahoo.c @@ -0,0 +1,106 @@ +#include "assets.h" +#include "json_curl.h" +#include "quotes.h" +#include "yahoo.h" + +#include +#include +#include + +#include + +int yahoo_get_quote_symbols(struct asset **assets, int n, char **bufptr) +{ + size_t bufsize = 1024; + char *buf = malloc(bufsize); + if (!buf) return -1; + int len = 0; + + for (int i = 0; i < n; ++i) { + if (assets[i]->type == CRYPTO) { + int c; +retry: + if (strcmp(assets[i]->symbol, "BTC") == 0) { + c = snprintf(buf + len, bufsize - len, "%s-USD,", + assets[i]->symbol); + } else { + c = snprintf(buf + len, bufsize - len, "%s-USD,%s-BTC,", + assets[i]->symbol, assets[i]->symbol); + } + + if (c < 0) + continue; + if ((unsigned)c >= bufsize - len) { + char *tmpbuf = realloc(buf, (bufsize *= 2)); + if (tmpbuf) { + buf = tmpbuf; + } else { + free(buf); + return -1; + } + + goto retry; + } + + len += c; + } + } + + buf[--len] = '\0'; + *bufptr = buf; + return len; +} + +static json_object *fetch_quotes(const char *symbols) +{ + CURL *curl = curl_easy_init(); + if (!curl) return NULL; + + char base[] = "https://query1.finance.yahoo.com/v7/finance/quote?symbols="; + size_t len_symbols = strlen(symbols); + char uri[sizeof(base) + len_symbols]; + memcpy(uri, base, sizeof(base) - 1); + memcpy(uri + sizeof(base) - 1, symbols, len_symbols + 1); + + json_object *json = json_curl_perform(curl, uri); + curl_easy_cleanup(curl); + return json; +} + +int yahoo_get_quotes(const char *symbols, struct quote ***quotes_ptr) +{ + json_object *tmp, *json = fetch_quotes(symbols); + json_object_object_get_ex(json, "quoteResponse", &tmp); + json_object_object_get_ex(tmp, "result", &tmp); + + int n = json_object_array_length(tmp); + struct quote **quotes = calloc(n, sizeof(**quotes)); + *quotes_ptr = quotes; + + for (int i = 0; i < n; ++i) { + struct quote *q = calloc(1, sizeof(*q)); + json_object *q_tmp, *q_json = json_object_array_get_idx(tmp, i); + + json_object_object_get_ex(q_json, "quoteType", &q_tmp); + json_object_object_get_ex(q_json, + (strcmp(json_object_get_string(q_tmp), "CRYPTOCURRENCY") == 0) ? + "fromCurrency" : "symbol", + &q_tmp); + q->symbol = strdup(json_object_get_string(q_tmp)); + + json_object_object_get_ex(q_json, "currency", &q_tmp); + q->currency = strdup(json_object_get_string(q_tmp)); + + json_object_object_get_ex(q_json, "regularMarketPrice", &q_tmp); + q->price = json_object_get_double(q_tmp); + + json_object_object_get_ex(q_json, "regularMarketChangePercent", + &q_tmp); + q->change_percent = json_object_get_double(q_tmp); + + quotes[i] = q; + } + + json_object_put(json); + return n; +} -- cgit v1.2.3-70-g09d2