GList * json_api_get_items (const gchar *json, const gchar *root, jsonApiMapping *mapping, jsonApiItemCallbackFunc callback) { GList *items = NULL; JsonParser *parser = json_parser_new (); if (json_parser_load_from_data (parser, json, -1, NULL)) { JsonArray *array = json_node_get_array (json_get_node (json_parser_get_root (parser), root)); GList *elements = json_array_get_elements (array); GList *iter = elements; debug1 (DEBUG_PARSING, "JSON API: found items root node \"%s\"", root); while (iter) { JsonNode *node = (JsonNode *)iter->data; itemPtr item = item_new (); /* Parse default feeds */ item_set_id (item, json_api_get_string (node, mapping->id)); item_set_title (item, json_api_get_string (node, mapping->title)); item_set_source (item, json_api_get_string (node, mapping->link)); item->time = json_api_get_int (node, mapping->updated); item->readStatus = json_api_get_bool (node, mapping->read); item->flagStatus = json_api_get_bool (node, mapping->flag); if (mapping->negateRead) item->readStatus = !item->readStatus; /* Handling encoded content */ const gchar *content; gchar *xhtml; content = json_api_get_string (node, mapping->description); if (mapping->xhtml) { xhtml = xhtml_extract_from_string (content, NULL); item_set_description (item, xhtml); xmlFree (xhtml); } else { item_set_description (item, content); } /* Optional meta data */ const gchar *tmp = json_api_get_string (node, mapping->author); if (tmp) item->metadata = metadata_list_append (item->metadata, "author", tmp); items = g_list_append (items, (gpointer)item); /* Allow optional item callback to process stuff */ if (callback) (*callback)(node, item); iter = g_list_next (iter); } g_list_free (elements); g_object_unref (parser); } else { debug1 (DEBUG_PARSING, "Could not parse JSON \"%s\"", json); } return items; }
static void ttrss_feed_subscription_process_update_result (subscriptionPtr subscription, const struct updateResult* const result, updateFlags flags) { if (result->data && result->httpstatus == 200) { JsonParser *parser = json_parser_new (); if (json_parser_load_from_data (parser, result->data, -1, NULL)) { JsonArray *array = json_node_get_array (json_get_node (json_parser_get_root (parser), "content")); GList *elements = json_array_get_elements (array); GList *iter = elements; GList *items = NULL; /* We expect to get something like this [{"id":118, "unread":true, "marked":false, "updated":1287927675, "is_updated":false, "title":"IBM Says New ...", "link":"http:\/\/rss.slashdot.org\/~r\/Slashdot\/slashdot\/~3\/ALuhNKO3NV4\/story01.htm", "feed_id":"5", "content":"coondoggie writes ..." }, {"id":117, "unread":true, "marked":false, "updated":1287923814, [...] */ while (iter) { JsonNode *node = (JsonNode *)iter->data; itemPtr item = item_new (); gchar *id; const gchar *content; gchar *xhtml; id = g_strdup_printf ("%" G_GINT64_FORMAT, json_get_int (node, "id")); item_set_id (item, id); g_free (id); item_set_title (item, json_get_string (node, "title")); item_set_source (item, json_get_string (node, "link")); content = json_get_string (node, "content"); xhtml = xhtml_extract_from_string (content, NULL); item_set_description (item, xhtml); xmlFree (xhtml); item->time = json_get_int (node, "updated"); if (json_get_bool (node, "unread")) { item->readStatus = FALSE; } else { item->readStatus = TRUE; } if (json_get_bool (node, "marked")) item->flagStatus = TRUE; items = g_list_append (items, (gpointer)item); iter = g_list_next (iter); } g_list_free (elements); /* merge against feed cache */ if (items) { itemSetPtr itemSet = node_get_itemset (subscription->node); gint newCount = itemset_merge_items (itemSet, items, TRUE /* feed valid */, FALSE /* markAsRead */); itemlist_merge_itemset (itemSet); itemset_free (itemSet); feedlist_node_was_updated (subscription->node, newCount); } subscription->node->available = TRUE; } else { subscription->node->available = FALSE; g_string_append (((feedPtr)subscription->node->data)->parseErrors, _("Could not parse JSON returned by TinyTinyRSS API!")); } g_object_unref (parser); } else { subscription->node->available = FALSE; } }