Extend commit 25680305095bfcedaa46cb017182544183ab743b to the whole cpu object.
[monky] / src / ccurl_thread.c
index d9d9717..0dbe88e 100644 (file)
@@ -1,9 +1,11 @@
-/*
+/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+ * vim: ts=4 sw=4 noet ai cindent syntax=c
+ *
  * Conky, a system monitor, based on torsmo
  *
  * Please see COPYING for details
  *
- * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
  *     (see AUTHORS)
  * All rights reserved.
  *
@@ -24,6 +26,7 @@
 #include "conky.h"
 #include "logging.h"
 #include "ccurl_thread.h"
+#include "text_object.h"
 
 #ifdef DEBUG
 #include <assert.h>
 #include <curl/types.h>
 #include <curl/easy.h>
 
+/*
+ * The following code is the conky curl thread lib, which can be re-used to
+ * create any curl-based object (see weather and rss).  Below is an
+ * implementation of a curl-only object ($curl) which can also be used as an
+ * example.
+ */
 typedef struct _ccurl_memory_t {
        char *memory;
        size_t size;
 } ccurl_memory_t;
 
+/* finds a location based on uri in the list provided */
 ccurl_location_t *ccurl_find_location(ccurl_location_t **locations_head, char *uri)
 {
        ccurl_location_t *tail = *locations_head;
@@ -50,6 +60,7 @@ ccurl_location_t *ccurl_find_location(ccurl_location_t **locations_head, char *u
                tail = tail->next;
        }
        if (!tail) { /* new location!!!!!!! */
+               DBGP("new curl location: '%s'", uri);
                new = malloc(sizeof(ccurl_location_t));
                memset(new, 0, sizeof(ccurl_location_t));
                new->uri = strndup(uri, text_buffer_size);
@@ -67,6 +78,7 @@ ccurl_location_t *ccurl_find_location(ccurl_location_t **locations_head, char *u
        return new;
 }
 
+/* iterates over the list provided, frees stuff (list item, uri, result) */
 void ccurl_free_locations(ccurl_location_t **locations_head)
 {
        ccurl_location_t *tail = *locations_head;
@@ -82,6 +94,7 @@ void ccurl_free_locations(ccurl_location_t **locations_head)
        *locations_head = 0;
 }
 
+/* callback used by curl for writing the received data */
 size_t ccurl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
 {
        size_t realsize = size * nmemb;
@@ -97,7 +110,7 @@ size_t ccurl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *d
 }
 
 
-
+/* fetch our datums */
 void ccurl_fetch_data(ccurl_location_t *curloc)
 {
        CURL *curl = NULL;
@@ -109,28 +122,36 @@ void ccurl_fetch_data(ccurl_location_t *curloc)
        chunk.memory = NULL;
        chunk.size = 0;
 
-       curl = curl_easy_init();
-       if (curl) {
-               curl_easy_setopt(curl, CURLOPT_URL, curloc->uri);
-               curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-               curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback);
-               curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
-               curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0");
-
-               res = curl_easy_perform(curl);
-               if (res == CURLE_OK && chunk.size) {
-                       timed_thread_lock(curloc->p_timed_thread);
-                       (*curloc->process_function)(curloc->result, chunk.memory);
-                       timed_thread_unlock(curloc->p_timed_thread);
-                       free(chunk.memory);
-               } else {
-                       ERR("weather: no data from server");
-               }
+       if (curl_global_init(CURL_GLOBAL_ALL) == 0) {
+               curl = curl_easy_init();
+               if (curl) {
+                       DBGP("reading curl data from '%s'", curloc->uri);
+                       curl_easy_setopt(curl, CURLOPT_URL, curloc->uri);
+                       curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+                       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback);
+                       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
+                       curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0");
 
-               curl_easy_cleanup(curl);
-       }
+                       res = curl_easy_perform(curl);
+                       if (res == CURLE_OK && chunk.size) {
+                               long http_status_code;
 
-       return;
+                               if(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code) == CURLE_OK && http_status_code == 200) {
+                                       timed_thread_lock(curloc->p_timed_thread);
+                                       (*curloc->process_function)(curloc->result, chunk.memory);
+                                       timed_thread_unlock(curloc->p_timed_thread);
+                               } else {
+                                       NORM_ERR("curl: no data from server");
+                               }
+                               free(chunk.memory);
+                       } else {
+                               NORM_ERR("curl: no data from server");
+                       }
+
+                       curl_easy_cleanup(curl);
+               }
+               curl_global_cleanup();
+       }
 }
 
 void *ccurl_thread(void *) __attribute__((noreturn));
@@ -145,12 +166,12 @@ void ccurl_init_thread(ccurl_location_t *curloc, int interval)
                                (void *)curloc, interval * 1000000);
 
        if (!curloc->p_timed_thread) {
-               ERR("curl thread: error creating timed thread");
+               NORM_ERR("curl thread: error creating timed thread");
        }
        timed_thread_register(curloc->p_timed_thread,
                        &curloc->p_timed_thread);
        if (timed_thread_run(curloc->p_timed_thread)) {
-               ERR("curl thread: error running timed thread");
+               NORM_ERR("curl thread: error running timed thread");
        }
 }
 
@@ -167,18 +188,32 @@ void *ccurl_thread(void *arg)
        /* never reached */
 }
 
+
+/*
+ * This is where the $curl section begins.
+ */
+
+struct curl_data {
+       char uri[128];
+       float interval;
+};
+
+/* internal location pointer for use by $curl, no touchy */
 static ccurl_location_t *ccurl_locations_head = 0;
 
+/* used to free data used by $curl */
 void ccurl_free_info(void)
 {
        ccurl_free_locations(&ccurl_locations_head);
 }
 
-void ccurl_parse_data(void *result, const char *data)
+/* straight copy, used by $curl */
+static void ccurl_parse_data(void *result, const char *data)
 {
        strncpy(result, data, max_user_text);
 }
 
+/* prints result data to text buffer, used by $curl */
 void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
 {
        ccurl_location_t *curloc = ccurl_find_location(&ccurl_locations_head, uri);
@@ -188,7 +223,7 @@ void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
                curloc->process_function = &ccurl_parse_data;
                ccurl_init_thread(curloc, interval);
                if (!curloc->p_timed_thread) {
-                       ERR("error setting up weather thread");
+                       NORM_ERR("error setting up curl thread");
                }
        }
 
@@ -197,3 +232,40 @@ void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
        timed_thread_unlock(curloc->p_timed_thread);
 }
 
+void curl_parse_arg(struct text_object *obj, const char *arg)
+{
+       int argc;
+       struct curl_data *cd;
+       float interval = 0;
+
+       cd = malloc(sizeof(struct curl_data));
+       memset(cd, 0, sizeof(struct curl_data));
+
+       argc = sscanf(arg, "%127s %f", cd->uri, &interval);
+       if (argc < 1) {
+               free(cd);
+               NORM_ERR("wrong number of arguments for $curl");
+               return;
+       }
+       cd->interval = interval > 0 ? interval * 60 : 15*60;
+       obj->data.opaque = cd;
+}
+
+void curl_print(struct text_object *obj, char *p, int p_max_size)
+{
+       struct curl_data *cd = obj->data.opaque;
+
+       if (!cd || !cd->uri) {
+               NORM_ERR("error processing Curl data");
+               return;
+       }
+       ccurl_process_info(p, p_max_size, cd->uri, cd->interval);
+}
+
+void curl_obj_free(struct text_object *obj)
+{
+       if (obj->data.opaque) {
+               free(obj->data.opaque);
+               obj->data.opaque = NULL;
+       }
+}