1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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;
}
|