int node_process(char cmd, mxml_node_t *tree, char *key, char *val, int num) { mxml_node_t *node = NULL; switch (cmd) { case 'a': node = xpath_create(tree, key, num); if(NULL != node) { // although node-text is empty, keep empty mxmlNewText(node, 0, val); } else { eprintf("%s exist\n", key); // return __LINE__; } break; case 'd': node = xpath_find(tree, key, num); if(NULL != node) { mxmlDelete(node); } break; case 'w': node = xpath_find(tree, key, num); if (node == NULL) { eprintf("not found: [%d]%s\n", num, key); return __LINE__; } if (NULL != node->child) { // printf("set\n"); mxmlSetText(node->child, 0, val); // mxmlSetTextf() doesn't work } else { mxmlNewText(node, 0, val); } break; case 'r': node = xpath_find(tree, key, num); if (NULL != node) { // mxml-2.8 vs mxml-2.7 -> (node->child) vs (node->child->value.text.string) // printf("%p\n", (node->child)); if (node->child == NULL) { eprintf("%s __got_empty_text__\n", key); return __LINE__; } else { printf("%d %s %s\n", num, key, trimsps(node->child->value.opaque)); } } else { eprintf("not found: [%d]%s\n", num, key); return __LINE__; } } return 0; }
/* * Check if folder of a node changed in Google Reader and move * node to the folder with the same name. */ static void aol_source_update_folder (xmlNodePtr match, AolSourcePtr gsource, nodePtr node) { xmlNodePtr xml; xmlChar *label; const gchar *ptitle; nodePtr parent; /* check if label of a feed changed */ parent = node->parent; ptitle = node_get_title (parent); xml = xpath_find (match, "./list[@name='categories']/object/string[@name='label']"); if (xml) { label = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); if (parent == gsource->root || ! g_str_equal (label, ptitle)) { debug2 (DEBUG_UPDATE, "GSource feed label changed for %s to '%s'", node->id, label); parent = aol_source_find_or_create_folder ((gchar*)label, gsource->root); node_reparent (node, parent); } xmlFree (label); } else { /* if feed has no label and parent is not gsource root, reparent to gsource root */ if (parent != gsource->root) node_reparent (node, gsource->root); } }
static void google_source_quick_update_helper (xmlNodePtr match, gpointer userdata) { GoogleSourcePtr gsource = (GoogleSourcePtr) userdata; xmlNodePtr xmlNode; xmlChar *id, *newestItemTimestamp; nodePtr node = NULL; const gchar *oldNewestItemTimestamp; xmlNode = xpath_find (match, "./string[@name='id']"); id = xmlNodeGetContent (xmlNode); if (g_str_has_prefix (id, "feed/")) node = google_source_get_node_by_source (gsource, id + strlen ("feed/")); else if (g_str_has_suffix (id, "broadcast-friends")) node = google_source_get_node_by_source (gsource, id); else { xmlFree (id); return; } if (node == NULL) { xmlFree (id); return; } xmlNode = xpath_find (match, "./number[@name='newestItemTimestampUsec']"); newestItemTimestamp = xmlNodeGetContent (xmlNode); oldNewestItemTimestamp = g_hash_table_lookup (gsource->lastTimestampMap, node->subscription->source); if (!oldNewestItemTimestamp || (newestItemTimestamp && !g_str_equal (newestItemTimestamp, oldNewestItemTimestamp))) { debug3(DEBUG_UPDATE, "GoogleSource: autoupdating %s " "[oldtimestamp%s, timestamp %s]", id, oldNewestItemTimestamp, newestItemTimestamp); g_hash_table_insert (gsource->lastTimestampMap, g_strdup (node->subscription->source), g_strdup (newestItemTimestamp)); subscription_update (node->subscription, 0); } if (newestItemTimestamp) xmlFree (newestItemTimestamp); xmlFree (id); }
static void google_source_check_for_removal (nodePtr node, gpointer user_data) { gchar *expr = NULL; if (g_str_equal (node->subscription->source, GOOGLE_READER_BROADCAST_FRIENDS_URL)) return ; if (IS_FEED (node)) { expr = g_strdup_printf ("/object/list[@name='subscriptions']/object/string[@name='id'][. = 'feed/%s']", node->subscription->source); } else { g_warning ("opml_source_check_for_removal(): This should never happen..."); return; } if (!xpath_find ((xmlNodePtr)user_data, expr)) { debug1 (DEBUG_UPDATE, "removing %s...", node_get_title (node)); feedlist_node_removed (node); } else { debug1 (DEBUG_UPDATE, "keeping %s...", node_get_title (node)); } g_free (expr); }
static void theoldreader_source_check_for_removal (nodePtr node, gpointer user_data) { gchar *expr = NULL; if (IS_FEED (node)) { expr = g_strdup_printf ("/object/list[@name='subscriptions']/object/string[@name='id'][. = 'feed/%s']", node->subscription->source); } else if (IS_FOLDER (node)) { node_foreach_child_data (node, theoldreader_source_check_for_removal, user_data); expr = g_strdup_printf ("/object/list[@name='subscriptions']/object/list[@name='categories']/object[string='%s']", node->title); } else { g_warning ("theoldreader_source_check_for_removal(): This should never happen..."); return; } if (!xpath_find ((xmlNodePtr)user_data, expr)) { debug1 (DEBUG_UPDATE, "removing %s...", node_get_title (node)); feedlist_node_removed (node); } else { debug1 (DEBUG_UPDATE, "keeping %s...", node_get_title (node)); } g_free (expr); }
static void google_source_merge_feed (xmlNodePtr match, gpointer user_data) { GoogleSourcePtr gsource = (GoogleSourcePtr)user_data; nodePtr node; GSList *iter; xmlNodePtr xml; xmlChar *title = NULL, *id = NULL; gchar *url = NULL; xml = xpath_find (match, "./string[@name='title']"); if (xml) title = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); xml = xpath_find (match, "./string[@name='id']"); if (xml) { id = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); url = g_strdup(id + strlen ("feed/")); } /* Note: ids look like "feed/http://rss.slashdot.org" */ if (id && title) { /* check if node to be merged already exists */ iter = gsource->root->children; while (iter) { node = (nodePtr)iter->data; if (g_str_equal (node->subscription->source, url)) { node->subscription->type = &googleSourceFeedSubscriptionType; goto cleanup ; } iter = g_slist_next (iter); } debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &googleSourceFeedSubscriptionType; node_set_parent (node, gsource->root, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); } else g_warning("Unable to parse subscription information from Google"); cleanup: if (id) xmlFree (id); if (title) xmlFree (title); g_free (url) ; }
static void aol_source_merge_feed (xmlNodePtr match, gpointer user_data) { AolSourcePtr gsource = (AolSourcePtr)user_data; nodePtr node, parent = NULL, subnode = NULL; GSList *iter, *iter_sub; xmlNodePtr xml; xmlChar *title = NULL, *id = NULL, *label = NULL; gchar *url = NULL; xml = xpath_find (match, "./string[@name='title']"); if (xml) title = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); xml = xpath_find (match, "./string[@name='id']"); if (xml) { id = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); url = g_strdup (id + strlen ("feed/")); } /* Note: ids look like "feed/http://rss.slashdot.org" */ if (id && title) { /* check if node to be merged already exists */ iter = gsource->root->children; while (iter) { node = (nodePtr)iter->data; if (node->subscription != NULL && g_str_equal (node->subscription->source, url)) { node->subscription->type = &aolSourceFeedSubscriptionType; aol_source_update_folder (match, gsource, node); goto cleanup; } else if (node->type->capabilities & NODE_CAPABILITY_SUBFOLDERS) { iter_sub = node->children; while (iter_sub) { subnode = (nodePtr)iter_sub->data; if (subnode->subscription != NULL && g_str_equal (subnode->subscription->source, url)) { subnode->subscription->type = &aolSourceFeedSubscriptionType; aol_source_update_folder (match, gsource, subnode); goto cleanup; } iter_sub = g_slist_next (iter_sub); } } iter = g_slist_next (iter); } /* if a new feed contains label, put its node under a folder with the same name */ xml = xpath_find (match, "./list[@name='categories']/object/string[@name='label']"); if (xml) { label = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); parent = aol_source_find_or_create_folder ((gchar*)label, gsource->root); xmlFree (label); } else { parent = gsource->root; } g_assert (NULL != parent); debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &aolSourceFeedSubscriptionType; node_set_parent (node, parent, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); } else { g_warning("Unable to parse subscription information from Google"); } cleanup: xmlFree (id); xmlFree (title); g_free (url) ; }