summaryrefslogtreecommitdiff
path: root/yahoo.c
diff options
context:
space:
mode:
Diffstat (limited to 'yahoo.c')
-rw-r--r--yahoo.c106
1 files changed, 106 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <json-c/json.h>
+
+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;
+}