From 9c15f41e101b30223db86bd5e2f1f5c8067d40ed Mon Sep 17 00:00:00 2001 From: James Shiffer <2191476+scoliono@users.noreply.github.com> Date: Wed, 31 Mar 2021 16:05:45 -0700 Subject: [PATCH] added company stats, fixed memory leaks --- FemMonitor/booru.c | 17 ++--- FemMonitor/company.c | 152 +++++++++++++++++++++++++++++++++++++++++++ FemMonitor/company.h | 6 +- FemMonitor/howfeed.c | 2 +- 4 files changed, 164 insertions(+), 13 deletions(-) diff --git a/FemMonitor/booru.c b/FemMonitor/booru.c index b10af7e..f75bb4f 100644 --- a/FemMonitor/booru.c +++ b/FemMonitor/booru.c @@ -66,17 +66,11 @@ void* booru_refresh(void* arg) gettimeofday(&start, NULL); CURLcode res; + CURLcode res2; struct MemoryStruct posts_data = geturl(curl, "http://fembooru.jp/api/danbooru/find_posts", &res); + struct MemoryStruct tags_data = geturl(curl, "http://fembooru.jp/api/danbooru/find_tags", &res2); - if (res != CURLE_OK) - { - on_curl_error(window, res); - goto cleanup; - } - - struct MemoryStruct tags_data = geturl(curl, "http://fembooru.jp/api/danbooru/find_tags", &res); - - if (res != CURLE_OK) + if (res != CURLE_OK || res2 != CURLE_OK) { on_curl_error(window, res); goto cleanup; @@ -137,9 +131,10 @@ void* booru_refresh(void* arg) wattroff(window, COLOR_PAIR(COLORS_SUCCESS)); mvwprintw(window, START_ROW, START_COL, "%s posts", attr->children->content); - // get first 3 tags xmlFreeDoc(doc); - doc = xmlReadMemory(tags_data.memory, tags_data.size, "noname.xml", NULL, 0); + + // get first 3 tags + doc = xmlReadMemory(tags_data.memory, tags_data.size, "noname.xml", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING); if (doc == NULL) { on_xml_error(window); diff --git a/FemMonitor/company.c b/FemMonitor/company.c index 64b6de5..0d1000a 100644 --- a/FemMonitor/company.c +++ b/FemMonitor/company.c @@ -6,4 +6,156 @@ // Copyright © 2021 FemboyFinancial. All rights reserved. // +#include +#include +#include +#include +#include +#include + +#include "common.h" #include "company.h" + + +static CURL* curl = NULL; +static WINDOW* window = NULL; +static htmlDocPtr doc = NULL; +static xmlXPathContext* ctx = NULL; +static xmlXPathObject* xpathObj = NULL; +static int height; +static int width; + +void company_init(WINDOW* win, int h, int w) +{ + curl = curl_easy_init(); + window = win; + height = h; + width = w; + + mvwprintw(window, 0, START_COL, " Company "); + if (curl == NULL) + { + wattron(window, COLOR_PAIR(COLORS_FAILURE)); + mvwprintw(window, 0, TITLE_START_COL, " ERROR "); + mvwprintw(window, START_ROW, START_COL, "Failed to initialize libcurl!"); + wattroff(window, COLOR_PAIR(COLORS_FAILURE)); + curl_global_cleanup(); + } + + wrefresh(window); +} + +// I don't need a whole library to parse a json file that only holds one thing lul +bool parse_meet_time(const char* json, struct tm* time) +{ + const char* prop = "\"LastMeetingTime\":\""; + json = strstr(json, prop); + if (json == NULL) + return FALSE; + json += strlen(prop); + strptime(json, "%Y-%m-%dT%H:%M:%S.", time); + return TRUE; +} + +void* company_refresh(void* arg) +{ + for ( ; ; sleep(5)) + { + CURLcode res; + // check if femfinancial is up + struct MemoryStruct ff_data = geturl(curl, "http://ff.howfeed.biz", &res); + + // get random reference from booru + struct MemoryStruct booru_data = geturl(curl, "http://fembooru.jp", NULL); + + // get most recent meeting time + struct MemoryStruct meet_data = geturl(curl, "http://howfeed.biz/api/meet?token=1445", NULL); + + doc = htmlReadMemory(booru_data.memory, booru_data.size, "nopath.xml", NULL, HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING); + if (doc == NULL) + { + on_xml_error(window); + goto cleanup; + } + + /* Create xpath evaluation context */ + ctx = xmlXPathNewContext(doc); + if (ctx == NULL) + { + on_xml_error(window); + goto cleanup; + } + + xpathObj = xmlXPathEvalExpression("//div[@id=\"tips\"]", ctx); + if (xpathObj == NULL) + { + on_xml_error(window); + goto cleanup; + } + + htmlNodePtr div = xpathObj->nodesetval->nodeTab[0]; + if (div == NULL) + { + on_xml_error(window); + goto cleanup; + } + else + { + char* tagline = div->children->content; + // clear line + for (int i = START_COL; i < width - 1; ++i) + mvwprintw(window, START_ROW, i, " "); + // print the funny reference + mvwprintw(window, START_ROW, START_COL, "Random reference: %s", tagline); + } + + + struct tm lastmeeting; + mvwprintw(window, START_ROW+1, START_COL, "Last meeting:"); + wattron(window, WA_BOLD); + if (parse_meet_time(meet_data.memory, &lastmeeting)) + { + double diff_min = difftime(time(NULL), timegm(&lastmeeting)) / 60.0; + double diff_hr = diff_min / 60.0; + mvwprintw(window, START_ROW+1, START_COL+13, " %.0fh %.0fm ago", diff_hr, diff_min); + } + else + { + mvwprintw(window, START_ROW+1, START_COL+13, " a long time ago"); + } + wattroff(window, WA_BOLD); + + mvwprintw(window, START_ROW+2, START_COL, "FemboyFinancial website:"); + if (res == CURLE_OK) + { + wattron(window, COLOR_PAIR(COLORS_SUCCESS)); + mvwprintw(window, START_ROW+2, START_COL+24, " ONLINE"); + wattroff(window, COLOR_PAIR(COLORS_SUCCESS)); + } + else + { + wattron(window, COLOR_PAIR(COLORS_FAILURE)); + mvwprintw(window, START_ROW+2, START_COL+24, " OFFLINE"); + wattroff(window, COLOR_PAIR(COLORS_FAILURE)); + } + + wrefresh(window); + + cleanup: + if (xpathObj != NULL) + xmlXPathFreeObject(xpathObj); + if (ctx != NULL) + xmlXPathFreeContext(ctx); + if (doc != NULL) + xmlFreeDoc(doc); + free(ff_data.memory); + free(booru_data.memory); + free(meet_data.memory); + } +} + +void company_destroy() +{ + if (curl != NULL) + curl_easy_cleanup(curl); +} diff --git a/FemMonitor/company.h b/FemMonitor/company.h index b7f9362..5657205 100644 --- a/FemMonitor/company.h +++ b/FemMonitor/company.h @@ -9,7 +9,11 @@ #ifndef company_h #define company_h -#include +#include +void company_init(WINDOW* win, int h, int w); +void* company_refresh(void* arg); +/* Note: this function will not free the window! */ +void company_destroy(void); #endif /* company_h */ diff --git a/FemMonitor/howfeed.c b/FemMonitor/howfeed.c index 80288f4..515a896 100644 --- a/FemMonitor/howfeed.c +++ b/FemMonitor/howfeed.c @@ -95,7 +95,7 @@ void* howfeed_refresh(void* arg) gdrawbar(graph, index, response_times[index] / 100.0f); // get article count - doc = xmlReadMemory(article_data.memory, article_data.size, "noname.xml", NULL, 0); + doc = xmlReadMemory(article_data.memory, article_data.size, "noname.xml", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING); if (doc == NULL) { on_xml_error(window);