diff options
-rw-r--r-- | api.c | 100 | ||||
-rw-r--r-- | api.h | 14 | ||||
-rw-r--r-- | main.c | 14 | ||||
-rw-r--r-- | string-tick.c | 13 | ||||
-rw-r--r-- | string-tick.h | 7 |
5 files changed, 82 insertions, 66 deletions
@@ -249,63 +249,57 @@ double* morningstar_get_hist_5y(const char* symbol) { return api_data; } -void news_print_top_three(const char* ticker_name_string) { - char* url_encoded_string = calloc(128, sizeof(char)); - pointer_alloc_check(url_encoded_string); - for (int i = 0, j = 0; i < 128; i++, j++) { //Replace underscores and spaces with url encoded '%20's - if (ticker_name_string[i] == '_' || ticker_name_string[i] == ' ') { - memcpy(&url_encoded_string[i], "%20", 3); - i += 2; - } else url_encoded_string[i] = ticker_name_string[j]; +void iex_print_news(const char* symbol, int num_articles) { + if (num_articles > 50) + RET_MSG("You cannot request more than 50 articles."); + + char iex_api_string[URL_MAX_LENGTH]; + sprintf(iex_api_string, "https://api.iextrading.com/1.0/stock/%s/news/last/%d", symbol, num_articles); + String* pString = api_curl_data(iex_api_string, NULL); + if (pString == NULL) + return; + + if (strcmp(pString->data, "Unknown symbol") == 0) { // Invalid symbol + string_destroy(&pString); + RET_MSG("Invalid symbol."); } - char yearchar[16], news_api_string[256]; - time_t now = time(NULL); - struct tm* ts = localtime(&now); - ts->tm_mday -= 14; // Lowerbound date is 14 days earlier - mktime(ts); - strftime(yearchar, 16, "%Y-%m-%d", ts); - sprintf(news_api_string, "https://newsapi.org/v2/everything?sortBy=popularity&pageSize=3&language=en" - "&apiKey=1163c352d041460381f0a8273e60a9d1&from=%s&q=%s", yearchar, url_encoded_string); - free(url_encoded_string); - String* pString = api_curl_data(news_api_string, NULL); + Json* jobj = json_tokener_parse(pString->data); - if (strtol(json_object_to_json_string(json_object_object_get(jobj, "totalResults")), NULL, 10) > 0) - json_print_news(jobj); - else puts("No articles. Try a different input."); - json_object_put(jobj); - string_destroy(&pString); -} + size_t len = json_object_array_length(jobj); + if (len == 0) { + json_object_put(jobj); + string_destroy(&pString); + RET_MSG("No articles available."); + } -void json_print_news(const Json* jobj) { - Json* article_list = json_object_object_get(jobj, "articles"), * article; - char author_string[512], title_string[512], source_string[512], url_string[512], date_string[512], * shortened_url; - int results = (int) strtol(json_object_to_json_string(json_object_object_get(jobj, "totalResults")), NULL, 10); - if (results > 3) - results = 3; - for (int i = 0; i < results; i++) { - article = json_object_array_get_idx(article_list, (size_t) i); - strcpy(author_string, json_object_to_json_string(json_object_object_get(article, "author"))); - strip_char(author_string, '\\'); // Strip all attributes of escape characters - strcpy(title_string, json_object_to_json_string(json_object_object_get(article, "title"))); - strip_char(title_string, '\\'); - strcpy(source_string, - json_object_to_json_string(json_object_object_get(json_object_object_get(article, "source"), "name"))); - strip_char(source_string, '\\'); - strcpy(date_string, json_object_to_json_string(json_object_object_get(article, "publishedAt"))); - date_string[11] = '\"'; // End string after day of month - date_string[12] = '\0'; - strcpy(url_string, json_object_to_json_string(json_object_object_get(article, "url"))); - strip_char(url_string, '\\'); - strip_char(url_string, '\"'); - shortened_url = google_shorten_link(url_string); // Shorten link with google API - printf("Title: %s Source: %s ", title_string, source_string); - if (strcmp(author_string, "null") != 0) // Some articles don't list authors or dates - printf("Author: %s ", author_string); - if (strcmp(date_string, "null") != 0) - printf("Date: %s ", date_string); - printf("Url: \"%s\"\n", shortened_url); - free(shortened_url); + Json* idx; + const char* headline, * source, *url; + char date[DATE_MAX_LENGTH]; + for (size_t i = 0; i < len; i++) { + idx = json_object_array_get_idx(jobj, i); + headline = json_object_get_string(json_object_object_get(idx, "headline")); // Headline + source = json_object_get_string(json_object_object_get(idx, "source")); // Source + strncpy(date, json_object_get_string(json_object_object_get(idx, "datetime")), 10); // Date + date[10] = '\0'; // null terminate date before time + char summary[strlen(json_object_get_string(json_object_object_get(idx, "summary")))]; // Summary + strcpy(summary, json_object_get_string(json_object_object_get(idx, "summary"))); + strip_tags(summary); // Summary will be html formatted, so must strip tags + url = json_object_get_string(json_object_object_get(idx, "url")); // URL + char related[strlen(json_object_get_string(json_object_object_get(idx, "related")))]; // Related + strcpy(related, json_object_get_string(json_object_object_get(idx, "related"))); + int related_num = 0; + for (size_t j = 0; j < strlen(related); j++) { // List only first five related symbols + if (related[j] == ',') + related_num++; + if (related_num == 5) { + related[j] = '\0'; + break; + } + } + printf("%s | %s | %s\n%s\n%s | Related: %s\n\n", headline, source, date, summary, url, related); } + json_object_put(jobj); + string_destroy(&pString); } void api_print_info(const char* ticker_name_string) { @@ -9,7 +9,9 @@ #ifndef API_H #define API_H +#define DATE_MAX_LENGTH 16 #define SYMBOL_MAX_LENGTH 32 +#define URL_MAX_LENGTH 2048 #define EMPTY (-999) #include <stddef.h> @@ -111,17 +113,9 @@ double* morningstar_get_hist_5y(const char* symbol); /** * Prints the top three news articles by popularity pertaining to the given string, ticker_name_string. Spaces and * underscores will be url-encoded (replaced by "%20"). News API will be used for data. - * @param ticker_name_string the string to query + * @param symbol the string to query */ -void news_print_top_three(const char* ticker_name_string); - -/** - * Prints relevant information about up to three articles given a News API JSON formatted response object. Title, source, - * and URL will always be printed. The URL will be shortened by Google's URL-shortener API. If the author and date - * are specified, those will be printed as well. - * @param jobj the JSON array - */ -void json_print_news(const Json* jobj); +void iex_print_news(const char* symbol, int num_articles); /** * Prints information about the symbol ticker_name_string by calling the function json_print_news. @@ -27,9 +27,13 @@ int main(int argc, char* argv[]) { // Portfolio modify operation int modop = -1; - // News - if (strcmp(cmd, "news") == 0 && argc == 3 && strlen(sym) <= 32 && strlen(sym) > 1) - news_print_top_three(sym); + // News + if (strcmp(cmd, "news") == 0 && (argc == 3 || argc == 4)) { + int num_articles = 3; // Default + if (argc == 4) + num_articles = (int) strtol(argv[3], NULL, 10); + iex_print_news(sym, num_articles); + } //Encrypt/decrypt else if ((strcmp(cmd, "encrypt") == 0 || strcmp(cmd, "decrypt") == 0) && argc == 2) @@ -38,8 +42,12 @@ int main(int argc, char* argv[]) { // Info else if (strcmp(cmd, "info") == 0 && argc == 3) api_print_info(sym); + + // Graph else if (strcmp(cmd, "graph") == 0 && argc == 3) graph_main(sym, NULL); + + // Compare else if (strcmp(cmd, "cmp") == 0 && argc == 4) { char sym2[strlen(argv[3]) + 1]; strcpy(sym2, argv[3]); diff --git a/string-tick.c b/string-tick.c index 55b04aa28e60..47166012241b 100644 --- a/string-tick.c +++ b/string-tick.c @@ -32,6 +32,19 @@ char* strip_char(char* string, char c) { return string; } +char* strip_tags(char* string) { + size_t len = strlen(string); + int i, j; + for (i = 0, j = 0; j < (int) len; i++, j++) { + if (string[j] == '<') + while (string[j] != '>') + j++; + string[i] = string[j]; + } + string[i] = '\0'; + return string; +} + void string_write_portfolio(String* pString) { FILE* fp = fopen(portfolio_file, "w"); if (fp == NULL) diff --git a/string-tick.h b/string-tick.h index 71309f7849e3..93909c54fc73 100644 --- a/string-tick.h +++ b/string-tick.h @@ -60,6 +60,13 @@ void strtoupper(char* str); char* strip_char(char* string, char c); /** + * Returns the input string, stripped of all HTML tags. + * @param string input string + * @return input string + */ +char* strip_tags(char* string); + +/** * Overwrites the portfolio with the given pString * @param pString the String to overwrite with */ |