static void theoldreader_source_merge_feed (TheOldReaderSourcePtr source, const gchar *url, const gchar *title, const gchar *id, nodePtr folder) { nodePtr node; node = feedlist_find_node (source->root, NODE_BY_URL, url); if (!node) { 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 = source->root->source->type->feedSubscriptionType; /* Save TheOldReader feed id which we need to fetch items... */ node->subscription->metadata = metadata_list_append (node->subscription->metadata, "theoldreader-feed-id", id); db_subscription_update (node->subscription); node_set_parent (node, folder?folder:source->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 { node_source_update_folder (node, folder); } }
static gboolean ttrss_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "ttrss_feed_subscription_prepare_update_request()"); nodePtr root = node_source_root_from_node (subscription->node); ttrssSourcePtr source = (ttrssSourcePtr) root->data; const gchar *feed_id; gchar *source_name; debug0 (DEBUG_UPDATE, "preparing tt-rss feed subscription for update"); g_assert(source); if (source->loginState == TTRSS_SOURCE_STATE_NONE) { subscription_update (root->subscription, 0); return FALSE; } feed_id = metadata_list_get (subscription->metadata, "ttrss-feed-id"); if (!feed_id) { g_warning ("tt-rss feed without id! (%s)", subscription->node->title); return FALSE; } request->postdata = g_strdup_printf (TTRSS_JSON_HEADLINES, source->session_id, feed_id, 15 /* items to fetch */ ); source_name = g_strdup_printf (TTRSS_URL, metadata_list_get (root->subscription->metadata, "ttrss-url")); update_request_set_source (request, source_name); g_free (source_name); return TRUE; }
/* * Find a node by the name under root or create it. */ static nodePtr theoldreader_source_find_or_create_folder (const gchar *name, nodePtr root) { nodePtr folder = NULL; GSList *iter_parent; /* find a node by the name under root */ iter_parent = root->children; while (iter_parent) { if (g_str_equal (name, node_get_title (iter_parent->data))) { folder = (nodePtr)iter_parent->data; break; } iter_parent = g_slist_next (iter_parent); } /* if not found, create new folder */ if (!folder) { folder = node_new (folder_get_node_type ()); node_set_title (folder, name); node_set_parent (folder, root, -1); feedlist_node_imported (folder); subscription_update (folder->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); } return folder; }
/** * This function tries to find a feed link for a given HTTP URI. It * tries to download it. If it finds a valid feed source it parses * this source instead into the given feed parsing context. It also * replaces the HTTP URI with the found feed source. */ static void feed_parser_auto_discover (feedParserCtxtPtr ctxt) { gchar *source; if (ctxt->feed->parseErrors) g_string_truncate (ctxt->feed->parseErrors, 0); else ctxt->feed->parseErrors = g_string_new(NULL); debug1 (DEBUG_UPDATE, "Starting feed auto discovery (%s)", subscription_get_source (ctxt->subscription)); source = html_auto_discover_feed (ctxt->data, subscription_get_source (ctxt->subscription)); /* FIXME: we only need the !g_str_equal as a workaround after a 404 */ if (source && !g_str_equal (source, subscription_get_source (ctxt->subscription))) { debug1 (DEBUG_UPDATE, "Discovered link: %s", source); ctxt->failed = FALSE; subscription_set_source (ctxt->subscription, source); /* The feed that was processed wasn't the correct one, we need to redownload it. * Cancel the update in case there's one in progress */ subscription_cancel_update (ctxt->subscription); subscription_update (ctxt->subscription, FEED_REQ_RESET_TITLE); g_free (source); } else { debug0 (DEBUG_UPDATE, "No feed link found!"); g_string_append (ctxt->feed->parseErrors, _("The URL you want Liferea to subscribe to points to a webpage and the auto discovery found no feeds on this page. Maybe this webpage just does not support feed auto discovery.")); } }
/** * Add "broadcast-friends" to the list of subscriptions if required */ static void google_source_add_broadcast_subscription (GoogleSourcePtr gsource) { const gchar* title = "Friend's Shared Items"; GSList * iter = NULL; nodePtr node; iter = gsource->root->children; while (iter) { node = (nodePtr) iter->data ; if (!node->subscription || !node->subscription->source) continue; if (g_str_equal (node->subscription->source, GOOGLE_READER_BROADCAST_FRIENDS_URL)) { return; } iter = g_slist_next (iter); } /* aha! add it! */ node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (GOOGLE_READER_BROADCAST_FRIENDS_URL, NULL, NULL)); node->subscription->type = &googleSourceFeedSubscriptionType; node_set_parent (node, gsource->root, -1); feedlist_node_imported (node); subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); }
static gboolean reedah_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "preparing Reedah feed subscription for update\n"); ReedahSourcePtr source = (ReedahSourcePtr) node_source_root_from_node (subscription->node)->data; g_assert(source); if (source->root->source->loginState == NODE_SOURCE_STATE_NONE) { subscription_update (node_source_root_from_node (subscription->node)->subscription, 0) ; return FALSE; } if (!metadata_list_get (subscription->metadata, "reedah-feed-id")) { g_warning ("Skipping Reedah feed '%s' (%s) without id!", subscription->source, subscription->node->id); return FALSE; } debug0 (DEBUG_UPDATE, "Setting cookies for a Reedah subscription"); gchar* source_escaped = g_uri_escape_string(metadata_list_get (subscription->metadata, "reedah-feed-id"), NULL, TRUE); // FIXME: move to .h // FIXME: do not use 30 gchar* newUrl = g_strdup_printf ("http://www.reedah.com/reader/api/0/stream/contents/%s?client=liferea&n=30", source_escaped); update_request_set_source (request, newUrl); g_free (newUrl); g_free (source_escaped); update_request_set_auth_value (request, source->root->source->authToken); return TRUE; }
void packet_received(struct broadcast_conn *connection, const rimeaddr_t *from) { struct subscription_item *si; switch(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE)) { case MWARE_MSG_SUB: si = subscription_get(&(packetbuf_msg_sub())->id); if (si != NULL) { if (subscription_is_unsubscribed(si)) { subscription_reset_last_shout(si); } else { if (!subscription_update(si, from, (packetbuf_msg_sub())->sub.hops + 1)) { si = NULL; } } } else if (!subscription_is_too_far(&(packetbuf_msg_sub())->sub)) { const rimeaddr_t * parent; parent = (identifier_is_mine(&(packetbuf_msg_sub())->id) ? &rimeaddr_null : from); si = subscription_insert( &(packetbuf_msg_sub())->id, &(packetbuf_msg_sub())->sub, parent, (packetbuf_msg_sub())->sub.hops + 1); } if (si != NULL) { subscription_print(si, "rs"); subscription_sync_epoch(si, &(packetbuf_msg_sub())->sub); wind_item_timer(si, subscription_desync_jitter(si, &(packetbuf_msg_sub())->sub)); } break; case MWARE_MSG_PUB: si = subscription_get(&(packetbuf_msg_pub())->id); if (si == NULL || subscription_is_unsubscribed(si)) { break; } if (rimeaddr_cmp(&si->next_hop, from)) { subscription_update_last_heard(si); } else if (message_is_published_to_me()) { subscription_data_input(si, (packetbuf_msg_pub())->data, (packetbuf_msg_pub())->node_count); } break; case MWARE_MSG_UNSUB: si = subscription_get(&(packetbuf_msg_unsub())->id); if (si == NULL) { break; } subscription_print(si, "ru"); subscription_unsubscribe(si); break; } packetbuf_clear(); }
void node_update_subscription (nodePtr node, gpointer user_data) { if (node->source->root == node) { node_source_update (node); return; } if (node->subscription) subscription_update (node->subscription, GPOINTER_TO_UINT (user_data)); node_foreach_child_data (node, node_update_subscription, user_data); }
static nodePtr default_source_add_subscription (nodePtr node, subscriptionPtr subscription) { /* For the local feed list source subscriptions are always feed subscriptions implemented by the feed node and subscription type... */ nodePtr child = node_new (feed_get_node_type ()); node_set_title (child, _("New Subscription")); node_set_data (child, feed_new ()); node_set_subscription (child, subscription); /* feed subscription type is implicit */ feedlist_node_added (child); subscription_update (subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); return child; }
/* * Find a node by the name under root or create it. * * @param name Folder display name * @param parent Parent folder or source root node * * @returns a valid nodePtr */ static nodePtr ttrss_source_find_or_create_folder (const gchar *name, nodePtr parent) { nodePtr folder = NULL; folder = feedlist_find_node (parent, FOLDER_BY_TITLE, name); if (!folder) { folder = node_new (folder_get_node_type ()); node_set_title (folder, name); node_set_parent (folder, parent, -1); feedlist_node_imported (folder); subscription_update (folder->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); } return folder; }
static void on_authdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { AuthDialog *ad = AUTH_DIALOG (user_data); if (response_id == GTK_RESPONSE_OK) { subscription_set_auth_info (ad->priv->subscription, gtk_entry_get_text (GTK_ENTRY (ad->priv->username)), gtk_entry_get_text (GTK_ENTRY (ad->priv->password))); subscription_update (ad->priv->subscription, ad->priv->flags); } g_object_unref (ad); }
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 on_authdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { AuthDialog *ad = (AuthDialog *)user_data; if (response_id == GTK_RESPONSE_OK) { g_assert (NULL != ad->priv->subscription->updateOptions); g_free (ad->priv->subscription->updateOptions->username); g_free (ad->priv->subscription->updateOptions->password); ad->priv->subscription->updateOptions->username = g_strdup (BAD_CAST gtk_entry_get_text (GTK_ENTRY (ad->priv->username))); ad->priv->subscription->updateOptions->password = g_strdup (BAD_CAST gtk_entry_get_text (GTK_ENTRY (ad->priv->password))); subscription_update (ad->priv->subscription, ad->priv->flags); } g_object_unref (ad); }
static void ttrss_source_merge_feed (ttrssSourcePtr source, const gchar *url, const gchar *title, gint64 id) { nodePtr node; gchar *tmp; /* check if node to be merged already exists */ node = feedlist_find_node (source->root, NODE_BY_URL, url); if (!node) { 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 = &ttrssSourceFeedSubscriptionType; /* Save tt-rss feed id which we need to fetch items... */ tmp = g_strdup_printf ("%" G_GINT64_FORMAT, id); metadata_list_set (&node->subscription->metadata, "ttrss-feed-id", tmp); g_free (tmp); node_set_parent (node, source->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); /* Important: we must not loose the feed id! */ db_subscription_update (node->subscription); } debug2 (DEBUG_UPDATE, "updating folder for %s (%s)", title, url); ttrss_source_update_folder (source, node); }
static gboolean inoreader_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "preparing InoReader feed subscription for update\n"); nodePtr node = subscription->node; if (node->source->loginState == NODE_SOURCE_STATE_NONE) { subscription_update (node_source_root_from_node (node)->subscription, 0) ; return FALSE; } debug0 (DEBUG_UPDATE, "Setting cookies for a InoReader subscription"); gchar* source_escaped = g_uri_escape_string(request->source, NULL, TRUE); gchar* newUrl = g_strdup_printf ("http://www.inoreader.com/reader/atom/feed/%s", source_escaped); update_request_set_source (request, newUrl); g_free (newUrl); g_free (source_escaped); update_request_set_auth_value (request, node->source->authToken); return TRUE; }
void subscription_auto_update (subscriptionPtr subscription) { gint interval; guint flags = 0; GTimeVal now; if (!subscription) return; interval = subscription_get_update_interval (subscription); if (-1 == interval) conf_get_int_value (DEFAULT_UPDATE_INTERVAL, &interval); if (-2 >= interval || 0 == interval) return; /* don't update this subscription */ g_get_current_time (&now); if (subscription->updateState->lastPoll.tv_sec + interval*60 <= now.tv_sec) subscription_update (subscription, flags); }
static void inoreader_source_merge_feed (InoreaderSourcePtr source, const gchar *url, const gchar *title, const gchar *id) { nodePtr node; GSList *iter; /* check if node to be merged already exists */ iter = source->root->children; while (iter) { node = (nodePtr)iter->data; if (g_str_equal (node->subscription->source, url)) return; 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 = &inoreaderSourceFeedSubscriptionType; /* Save Inoreader feed id which we need to fetch items... */ node->subscription->metadata = metadata_list_append (node->subscription->metadata, "inoreader-feed-id", id); db_subscription_update (node->subscription); node_set_parent (node, source->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); }
static gboolean ttrss_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { nodePtr root = node_source_root_from_node (subscription->node); ttrssSourcePtr source = (ttrssSourcePtr) root->data; const gchar *feed_id; gchar *source_name; gint fetchCount; debug0 (DEBUG_UPDATE, "TinyTinyRSS preparing feed subscription for update"); // FIXME: if (!source->selfUpdating) trigger remote update first! g_assert(source); if (source->loginState == TTRSS_SOURCE_STATE_NONE) { subscription_update (root->subscription, 0); return FALSE; } feed_id = metadata_list_get (subscription->metadata, "ttrss-feed-id"); if (!feed_id) { g_warning ("Fatal: TinyTinyRSS feed without id! (%s)", subscription->node->title); return FALSE; } /* We can always max out as TinyTinyRSS does limit results itself */ fetchCount = feed_get_max_item_count (subscription->node); request->postdata = g_strdup_printf (TTRSS_JSON_HEADLINES, source->session_id, feed_id, fetchCount); source_name = g_strdup_printf (TTRSS_URL, source->url); update_request_set_source (request, source_name); g_free (source_name); return TRUE; }
static void on_propdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { SubscriptionPropDialog *spd = (SubscriptionPropDialog *)user_data; if(response_id == GTK_RESPONSE_OK) { gchar *newSource; const gchar *newFilter; gboolean needsUpdate = FALSE; subscriptionPtr subscription = spd->priv->subscription; nodePtr node = spd->priv->subscription->node; feedPtr feed = (feedPtr)node->data; if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "General" */ node_set_title(node, gtk_entry_get_text(GTK_ENTRY(spd->priv->feedNameEntry))); /* Source */ newSource = ui_subscription_dialog_decode_source(spd->priv); /* Filter handling */ newFilter = gtk_entry_get_text(GTK_ENTRY(liferea_dialog_lookup(spd->priv->dialog, "filterEntry"))); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(spd->priv->dialog, "filterCheckbox"))) && strcmp(newFilter,"")) { /* Maybe this should be a test to see if the file exists? */ if(subscription_get_filter(subscription) == NULL || strcmp(newFilter, subscription_get_filter(subscription))) { subscription_set_filter(subscription, newFilter); needsUpdate = TRUE; } } else { if(subscription_get_filter(subscription)) { subscription_set_filter(subscription, NULL); needsUpdate = TRUE; } } /* if URL has changed... */ if(strcmp(newSource, subscription_get_source(subscription))) { subscription_set_source(subscription, newSource); needsUpdate = TRUE; } g_free(newSource); /* Update interval handling */ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalNever")))) subscription_set_update_interval (subscription, -2); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalDefault")))) subscription_set_update_interval (subscription, -1); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalSpecific")))) { gint intervalUnit = gtk_combo_box_get_active (GTK_COMBO_BOX (spd->priv->refreshIntervalUnit)); gint updateInterval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spd->priv->refreshInterval)); if (intervalUnit == 1) updateInterval *= 60; /* hours */ if (intervalUnit == 2) updateInterval *= 1440; /* days */ subscription_set_update_interval (subscription, updateInterval); db_subscription_update (subscription); } } /* "Archive" handling */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDefault")))) feed->cacheLimit = CACHE_DEFAULT; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDisable")))) feed->cacheLimit = CACHE_DISABLE; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheUnlimited")))) feed->cacheLimit = CACHE_UNLIMITED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheLimited")))) feed->cacheLimit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "cacheItemLimit"))); if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "Download" Options */ subscription->updateOptions->dontUseProxy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "dontUseProxyCheck"))); } /* "Advanced" options */ feed->encAutoDownload = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enclosureDownloadCheck"))); node->loadItemLink = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "loadItemLinkCheck"))); feed->ignoreComments = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "ignoreCommentFeeds"))); feed->enforcePopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enforcePopupCheck"))); feed->preventPopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "preventPopupCheck"))); feed->markAsRead = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "markAsReadCheck"))); if (feed->enforcePopup && feed->preventPopup) feed->enforcePopup = FALSE; ui_node_update (node->id); feedlist_schedule_save (); db_subscription_update (subscription); if (needsUpdate) subscription_update (subscription, FEED_REQ_PRIORITY_HIGH); } g_object_unref(spd); }
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) ; }