From 9b8f568c5baef7fa8650ce30ff1c8f90b048b9a6 Mon Sep 17 00:00:00 2001 From: James Shiffer Date: Sat, 22 Apr 2023 01:48:02 -0700 Subject: [PATCH] Add craigslist car generator (closes #7) --- FemMonitor/booru.c | 29 ------------ FemMonitor/common.c | 1 + FemMonitor/craigslist.c | 101 ++++++++++++++++++++++++++++++++++++++++ FemMonitor/craigslist.h | 11 +++++ FemMonitor/main.c | 11 ++++- 5 files changed, 123 insertions(+), 30 deletions(-) create mode 100644 FemMonitor/craigslist.c create mode 100644 FemMonitor/craigslist.h diff --git a/FemMonitor/booru.c b/FemMonitor/booru.c index 8039489..e9ed80b 100644 --- a/FemMonitor/booru.c +++ b/FemMonitor/booru.c @@ -18,11 +18,8 @@ static xmlDoc* doc = NULL; static WINDOW* window = NULL; static CURL* curl = NULL; -static float* response_times = NULL; -static int iter = 0; static int width = 0; static int height = 0; -static struct Graph graph; void booru_init(WINDOW* win, int h, int w) { @@ -32,15 +29,8 @@ void booru_init(WINDOW* win, int h, int w) height = h; window = win; - graph.win = win; - graph.row = START_ROW + 4; - graph.col = START_COL + 1; - graph.width = w - graph.col - 2; - graph.height = h - graph.row - 1; - mvwprintw(window, 0, START_COL, " Fembooru.jp "); mvwprintw(window, START_ROW, START_COL, "Pinging..."); - mvwprintw(window, graph.row - 1, START_COL, "Response time (x100ms)"); if (curl == NULL) { wattron(window, COLOR_PAIR(COLORS_FAILURE)); @@ -50,18 +40,11 @@ void booru_init(WINDOW* win, int h, int w) curl_global_cleanup(); } - response_times = malloc(sizeof(float) * graph.width); - - gdrawylabels(graph); wrefresh(window); } void* booru_refresh(void* arg) { - // record the response time - struct timeval start, end; - gettimeofday(&start, NULL); - CURLcode res; CURLcode res2; struct MemoryStruct posts_data = geturl(curl, "http://fembooru.jp/api/danbooru/find_posts", &res); @@ -73,10 +56,6 @@ void* booru_refresh(void* arg) goto cleanup; } - gettimeofday(&end, NULL); - int index = iter++ % graph.width; - response_times[index] = (end.tv_sec - start.tv_sec) * 1000.0f + (end.tv_usec - start.tv_usec) / 1000.0f; - // clear status lines for (int i = TITLE_START_COL - 1; i < TITLE_START_COL + 7; ++i) mvwprintw(window, 0, i, " "); @@ -87,13 +66,6 @@ void* booru_refresh(void* arg) mvwprintw(window, i, j, " "); } - // clear graph if necessary - if (index == 0) - gclear(graph); - - // print status graph - gdrawbar(graph, index, response_times[index] / 100.0f); - // get post count doc = xmlReadMemory(posts_data.memory, posts_data.size, "noname.xml", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING); if (doc == NULL) @@ -161,5 +133,4 @@ void booru_destroy() { if (curl != NULL) curl_easy_cleanup(curl); - free(response_times); } diff --git a/FemMonitor/common.c b/FemMonitor/common.c index 8b1316f..bcb027c 100644 --- a/FemMonitor/common.c +++ b/FemMonitor/common.c @@ -39,6 +39,7 @@ struct MemoryStruct geturl(CURL* curl, char* url, CURLcode* res_out) curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_mem_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "FemMonitor/1.0"); struct MemoryStruct data; data.memory = malloc(1); /* will be grown as needed by the realloc above */ diff --git a/FemMonitor/craigslist.c b/FemMonitor/craigslist.c new file mode 100644 index 0000000..1be449d --- /dev/null +++ b/FemMonitor/craigslist.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include + +#include "craigslist.h" +#include "common.h" + +static WINDOW* window = NULL; +static CURL* curl = NULL; +static int width = 0; +static int height = 0; +static struct MemoryStruct car_data; + +void craigslist_init(WINDOW* win, int h, int w) +{ + // setup curl + curl = curl_easy_init(); + width = w; + height = h; + window = win; + + mvwprintw(window, 0, START_COL, " Craigslist "); + mvwprintw(window, START_ROW, START_COL, "Pinging..."); + 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(); + } + + CURLcode res; + car_data = geturl(curl, "https://sapi.craigslist.org/web/v8/postings/search/full?batch=1-0-360-0-0&bundleDuplicates=1&cc=US&lang=en&language=5&max_price=2000&purveyor=owner&searchPath=cta", &res); + + if (res != CURLE_OK) + { + on_curl_error(window, res); + } + + wrefresh(window); +} + +bool parse_rand_craigslist(const char* json, char* name, unsigned* price) +{ + srand(time(NULL)); + const char* items = strstr(json, ",\"items\":[["); + if (items == NULL) + return FALSE; + + int r = rand() % 400; + int i = 0; + const char* start_item = items; + const char* end_item = items; + do + { + start_item = strstr(end_item, "],\""); + end_item = strstr(start_item, "\"]"); + } + while (i++ < r && strstr(end_item, "],\"")); + strncpy(name, start_item + 3, end_item - start_item - 3); + //*price = atoi(); + *price = 0; + return TRUE; +} + +void* craigslist_refresh(void* arg) +{ + // clear status lines + for (int i = START_ROW; i < START_ROW+3; ++i) + { + for (int j = START_COL; j < width - 1; ++j) + mvwprintw(window, i, j, " "); + } + + char result[256] = {0}; + unsigned price; + if (parse_rand_craigslist(car_data.memory, result, &price)) + { + mvwprintw(window, START_ROW, START_COL, "%s", result); + } + else + { + wattron(window, COLOR_PAIR(COLORS_FAILURE)); + mvwprintw(window, START_ROW, START_COL, "Failed to parse Craigslist result"); + wattroff(window, COLOR_PAIR(COLORS_FAILURE)); + } + + // refresh view + wrefresh(window); +} + +void craigslist_destroy() +{ + if (curl != NULL) + curl_easy_cleanup(curl); + free(car_data.memory); +} diff --git a/FemMonitor/craigslist.h b/FemMonitor/craigslist.h new file mode 100644 index 0000000..0ec5be9 --- /dev/null +++ b/FemMonitor/craigslist.h @@ -0,0 +1,11 @@ +#ifndef craigslist_h +#define craigslist_h + +#include + +void craigslist_init(WINDOW* win, int h, int w); +void* craigslist_refresh(void* arg); +/* Note: this function will not free the window! */ +void craigslist_destroy(void); + +#endif /* craigslist_h */ diff --git a/FemMonitor/main.c b/FemMonitor/main.c index b1e0f0c..04b963f 100644 --- a/FemMonitor/main.c +++ b/FemMonitor/main.c @@ -17,6 +17,7 @@ #include "booru.h" #include "common.h" #include "company.h" +#include "craigslist.h" #include "mail.h" #include "numbers.h" @@ -71,9 +72,11 @@ int main(int argc, const char* argv[]) WINDOW* botmidleft = create_newwin(LINES/4, COLS/2, LINES*2/4, 0); WINDOW* botleft = create_newwin(LINES/4 - 1, COLS/2, LINES*3/4, 0); WINDOW* topright = create_newwin(LINES/2, COLS/2, 0, COLS/2); - WINDOW* botright = create_newwin(LINES/2 - 1, COLS/2, LINES/2, COLS/2); + WINDOW* midright = create_newwin(LINES/4, COLS/2, LINES*2/4, COLS/2); + WINDOW* botright = create_newwin(LINES/4 - 1, COLS/2, LINES*3/4, COLS/2); company_init(topleft, LINES/4, COLS/2); + craigslist_init(midright, LINES/4, COLS/2); numbers_init(topmidleft, LINES/4, COLS/2); bool_init(botmidleft, LINES/4, COLS/2); mail_init(botleft, LINES/4 - 1, COLS/2); @@ -85,6 +88,7 @@ int main(int argc, const char* argv[]) while ((ch = tolower(getch())) != KEY_QUIT) { company_refresh(NULL); + craigslist_refresh(NULL); numbers_refresh(NULL); bool_refresh(NULL); mail_refresh(NULL); @@ -109,10 +113,15 @@ int main(int argc, const char* argv[]) booru_destroy(); mail_destroy(); numbers_destroy(); + craigslist_destroy(); company_destroy(); destroy_win(topleft); + destroy_win(topmidleft); + destroy_win(botmidleft); destroy_win(botleft); + destroy_win(topright); + destroy_win(midright); destroy_win(botright); endwin();