static gchar * htmlview_render_item (itemPtr item, guint viewMode, gboolean summaryMode) { renderParamPtr params; gchar *output = NULL, *baseUrl = NULL; nodePtr node; xmlDocPtr doc; xmlNodePtr xmlNode; const gchar *text_direction = NULL; gboolean isMergedItemset; debug_enter ("htmlview_render_item"); /* don't use node from htmlView_priv as this would be wrong for folders and other merged item sets */ node = node_from_id (item->nodeId); isMergedItemset = (node != htmlView_priv.node); /* do the XML serialization */ doc = xmlNewDoc ("1.0"); xmlNode = xmlNewDocNode (doc, NULL, "itemset", NULL); xmlDocSetRootElement (doc, xmlNode); item_to_xml(item, xmlDocGetRootElement (doc)); text_direction = htmlview_get_item_direction (item); if (IS_FEED (node)) { xmlNodePtr feed; feed = xmlNewChild (xmlDocGetRootElement (doc), NULL, "feed", NULL); feed_to_xml (node, feed); } /* do the XSLT rendering */ params = render_parameter_new (); if (NULL != node_get_base_url (node)) { baseUrl = common_uri_escape (node_get_base_url (node)); render_parameter_add (params, "baseUrl='%s'", baseUrl); } render_parameter_add (params, "summary='%d'", summaryMode?1:0); render_parameter_add (params, "showFeedName='%d'", isMergedItemset?1:0); render_parameter_add (params, "single='%d'", (viewMode == ITEMVIEW_SINGLE_ITEM)?1:0); render_parameter_add (params, "txtDirection='%s'", text_direction); render_parameter_add (params, "appDirection='%s'", common_get_app_direction ()); output = render_xml (doc, "item", params); /* For debugging use: xmlSaveFormatFile("/tmp/test.xml", doc, 1); */ xmlFreeDoc (doc); g_free (baseUrl); debug_exit ("htmlview_render_item"); return output; }
// FIXME: this ought to be a subscription property! static guint itemset_get_max_item_count (itemSetPtr itemSet) { nodePtr node = node_from_id (itemSet->nodeId); if (node && IS_FEED (node)) return feed_get_max_item_count (node); return G_MAXUINT; }
void on_remove_items_activate (GtkMenuItem *menuitem, gpointer user_data) { nodePtr node; node = feedlist_get_selected (); // FIXME: use node type capability check if (node && (IS_FEED (node) || IS_NEWSBIN (node))) itemlist_remove_all_items (node); else ui_show_error_box (_("You must select a feed to delete its items!")); }
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 gboolean itemset_merge_item (itemSetPtr itemSet, GList *items, itemPtr item, gint maxChecks, gboolean allowUpdates) { gboolean allowStateChanges = FALSE; gboolean merge; nodePtr node; debug2 (DEBUG_UPDATE, "trying to merge \"%s\" to node id \"%s\"", item_get_title (item), itemSet->nodeId); g_assert (itemSet->nodeId); node = node_from_id (itemSet->nodeId); if (node) allowStateChanges = NODE_SOURCE_TYPE (node)->capabilities & NODE_SOURCE_CAPABILITY_ITEM_STATE_SYNC; /* first try to merge with existing item */ merge = itemset_generic_merge_check (items, item, maxChecks, allowUpdates, allowStateChanges); /* if it is a new item add it to the item set */ if (merge) { g_assert (!item->nodeId); g_assert (!item->id); item->nodeId = g_strdup (itemSet->nodeId); if (!item->parentNodeId) item->parentNodeId = g_strdup (itemSet->nodeId); /* step 1: write item to DB */ db_item_update (item); /* step 2: add to itemset */ itemSet->ids = g_list_prepend (itemSet->ids, GUINT_TO_POINTER (item->id)); /* step 3: trigger async enrichment of item description */ if (node && IS_FEED (node) && ((feedPtr)node->data)->html5Extract) feed_enrich_item (node->subscription, item); debug3 (DEBUG_UPDATE, "-> added \"%s\" (id=%d) to item set %p...", item_get_title (item), item->id, itemSet); /* step 4: duplicate detection, mark read if it is a duplicate */ if (item->validGuid) { GSList *iter, *duplicates; duplicates = iter = db_item_get_duplicates (item->sourceId); while (iter) { debug1 (DEBUG_UPDATE, "-> duplicate guid exists: #%lu", GPOINTER_TO_UINT (iter->data)); iter = g_slist_next (iter); } if (g_slist_length (duplicates) > 1) { item->readStatus = TRUE; /* no unread counting... */ item->popupStatus = FALSE; /* no notification... */ } g_slist_free (duplicates); } /* step 5: Check item for new enclosures to download */ if (node && (((feedPtr)node->data)->encAutoDownload)) { GSList *iter = metadata_list_get_values (item->metadata, "enclosure"); while (iter) { enclosurePtr enc = enclosure_from_string (iter->data); debug1 (DEBUG_UPDATE, "download enclosure (%s)", (gchar *)iter->data); enclosure_download (NULL, enc->url, FALSE /* non interactive */); iter = g_slist_next (iter); enclosure_free (enc); } } } else { debug2 (DEBUG_UPDATE, "-> not adding \"%s\" to node id \"%s\"...", item_get_title (item), itemSet->nodeId); item_unload (item); } return merge; }