#include "konasearch.h" #include "konaimage.h" #include #include #include // Function prototypes for local functions static void kona_search_posts_soup_cb (SoupSession *session, SoupMessage *msg, gpointer user_data); /*** GLIB object start ***/ struct searchResult_t { int count; GList *images; }; struct _KonaSearch { GObject parent_instance; // struct of parent (inherit) gchar *searchString; SoupSession *postsSession; struct searchResult_t searchResult; }; G_DEFINE_TYPE(KonaSearch, kona_search, G_TYPE_OBJECT) static void kona_search_class_init(KonaSearchClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); //object_class->set_property = kona_search_set_property; //object_class->get_property = kona_search_get_property; object_class->dispose = kona_search_dispose; object_class->finalize = kona_search_finalize; } static void kona_search_init (KonaSearch *self) { printf("kona_search_init\n"); } static void kona_search_dispose(GObject *self) { G_OBJECT_CLASS (kona_search_parent_class)->dispose((GObject*) self); } static void kona_search_finalize(GObject *self) { KonaSearch *ks = (KonaSearch*) self; g_free(ks->searchString); // TODO: Free SoupSession ks->postsSession G_OBJECT_CLASS (kona_search_parent_class)->finalize ((GObject*) self); } KonaSearch *kona_search_new(gchar *search) { KonaSearch *ks; ks = g_object_new(KONA_TYPE_SEARCH, 0); ks->searchString = g_strdup(search); ks->searchResult.count = -1; ks->searchResult.images = NULL; return ks; } /*** GLIB object end ***/ void kona_search_start(KonaSearch *self) { SoupMessage *msg; gchar *url; self->postsSession = soup_session_new(); url = g_strdup_printf("http://konachan.com/post.xml?tags=%s", self->searchString); msg = soup_message_new("GET", url); g_free(url); soup_session_queue_message(self->postsSession, msg, kona_search_posts_soup_cb, self); } static void kona_search_posts_soup_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { KonaSearch *ks; KonaImage *ki; kona_image_meta meta; gchar **tagsplit, **tagsplitc; GValue val = G_VALUE_INIT; xmlDocPtr xDocPtr; xmlNodePtr xNodePtr; xmlChar *key; ks = (KonaSearch*) user_data; g_value_init(&val, G_TYPE_POINTER); if (xDocPtr = xmlParseMemory(msg->response_body->data, msg->response_body->length)) { xNodePtr = xmlDocGetRootElement(xDocPtr); if (!xmlStrcmp(xNodePtr->name, "posts")) { ks->searchResult.count = atoi(xmlGetProp(xNodePtr, "count")); xNodePtr = xNodePtr->children; do { if (!xmlStrcmp(xNodePtr->name, "post")) { // Assemble meta information structure meta.id = atoi(xmlGetProp(xNodePtr, "id")); meta.width = atoi(xmlGetProp(xNodePtr, "width")); meta.height = atoi(xmlGetProp(xNodePtr, "height")); meta.image_url = xmlGetProp(xNodePtr, "file_url"); meta.preview_url = xmlGetProp(xNodePtr, "preview_url"); meta.tags = NULL; tagsplit = g_strsplit(xmlGetProp(xNodePtr, "tags"), " ", 100); for (tagsplitc = tagsplit; *tagsplitc; tagsplitc++) { meta.tags = g_list_append(meta.tags, *tagsplitc); } // Create new KonaImage ki = kona_image_new(); g_value_set_pointer(&val, (gpointer) &meta); g_object_set_property((GObject*) ki, "meta", &val); // Free temp string (copied by g_object_set_property) g_strfreev(tagsplit); // Add to list ks->searchResult.images = g_list_append(ks->searchResult.images, ki); } } while (xNodePtr = xNodePtr->next); } else { fprintf(stderr, "Error: Invalid XML root node!\n"); } } else { fprintf(stderr, "Error parsing XML result!\n"); } xmlFreeDoc(xDocPtr); } void kona_search_clear_full(KonaSearch *ks) { ks->searchResult.count = -1; g_list_free_full(ks->searchResult.images, g_object_unref); ks->searchResult.images = NULL; } void kona_search_clear(KonaSearch *ks) { ks->searchResult.count = -1; g_list_free(ks->searchResult.images); ks->searchResult.images = NULL; }