static void reedah_feed_subscription_process_update_result (subscriptionPtr subscription, const struct updateResult* const result, updateFlags flags) { if (result->data && result->httpstatus == 200) { GList *items = NULL; jsonApiMapping mapping; /* We expect to get something like this [{"crawlTimeMsec":"1375821312282", "id"::"tag:google.com,reader:2005\/item\/4ee371db36f84de2", "categories":["user\/15724899091976567759\/state\/com.google\/reading-list", "user\/15724899091976567759\/state\/com.google\/fresh"], "title":"Firefox 23 Arrives With New Logo, Mixed Content Blocker, and Network Monitor", "published":1375813680, "updated":1375821312, "alternate":[{"href":"http://rss.slashdot.org/~r/Slashdot/slashdot/~3/Q4450FchLQo/story01.htm","type":"text/html"}], "canonical":[{"href":"http://slashdot.feedsportal.com/c/35028/f/647410/s/2fa2b59c/sc[...]", "type":"text/html"}], "summary":{"direction":"ltr","content":"An anonymous reader writes [...]"}, "author":"Soulskill", "origin":{"streamId":"feed/http://rss.slashdot.org/Slashdot/slashdot","title":"Slashdot", "htmlurl":"http://slashdot.org/" }, [...] */ /* Note: The link and read status cannot be mapped as there might be multiple ones so the callback helper function extracts the first from the array */ mapping.id = "id"; mapping.title = "title"; mapping.link = NULL; mapping.description = "summary/content"; mapping.read = NULL; mapping.updated = "updated"; mapping.author = "author"; mapping.flag = "marked"; mapping.xhtml = TRUE; mapping.negateRead = TRUE; items = json_api_get_items (result->data, "items", &mapping, &reedah_item_callback); /* 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 Reedah API!")); } } else { subscription->node->available = FALSE; } }
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; } }
static void subscription_process_update_result (const struct updateResult * const result, gpointer user_data, guint32 flags) { subscriptionPtr subscription = (subscriptionPtr)user_data; nodePtr node = subscription->node; gboolean processing = FALSE; GTimeVal now; /* 1. preprocessing */ g_assert (subscription->updateJob); /* update the subscription URL on permanent redirects */ if ((301 == result->httpstatus) && result->source && !g_str_equal (result->source, subscription->updateJob->request->source)) { debug2 (DEBUG_UPDATE, "The URL of \"%s\" has changed permanently and was updated with \"%s\"", node_get_title(node), result->source); subscription_set_source (subscription, result->source); liferea_shell_set_status_bar (_("The URL of \"%s\" has changed permanently and was updated"), node_get_title(node)); } if (401 == result->httpstatus) { /* unauthorized */ auth_dialog_new (subscription, flags); } else if (410 == result->httpstatus) { /* gone */ subscription->discontinued = TRUE; node->available = TRUE; liferea_shell_set_status_bar (_("\"%s\" is discontinued. Liferea won't updated it anymore!"), node_get_title (node)); } else if (304 == result->httpstatus) { node->available = TRUE; liferea_shell_set_status_bar (_("\"%s\" has not changed since last update"), node_get_title(node)); } else { processing = TRUE; } subscription_update_error_status (subscription, result->httpstatus, result->returncode, result->filterErrors); subscription->updateJob = NULL; /* 2. call subscription type specific processing */ if (processing) SUBSCRIPTION_TYPE (subscription)->process_update_result (subscription, result, flags); /* 3. call favicon updating after subscription processing to ensure we have valid baseUrl for feed nodes... */ g_get_current_time (&now); if (favicon_update_needed (subscription->node->id, subscription->updateState, &now)) subscription_update_favicon (subscription); /* 4. generic postprocessing */ update_state_set_lastmodified (subscription->updateState, update_state_get_lastmodified (result->updateState)); update_state_set_cookies (subscription->updateState, update_state_get_cookies (result->updateState)); update_state_set_etag (subscription->updateState, update_state_get_etag (result->updateState)); g_get_current_time (&subscription->updateState->lastPoll); // FIXME: use new-items signal in itemview class itemview_update_node_info (subscription->node); itemview_update (); db_subscription_update (subscription); db_node_update (subscription->node); if (processing && subscription->node->newCount > 0) { feedlist_new_items (node->newCount); feedlist_node_was_updated (node); } }