예제 #1
0
static void
ttrss_source_check_node_for_removal (nodePtr node, gpointer user_data)
{
	JsonArray	*array = (JsonArray *)user_data;
	GList		*iter, *elements;
	gboolean	found = FALSE;

	if (IS_FOLDER (node)) {
		// FIXME: check folders too

		node_foreach_child_data (node, ttrss_source_check_node_for_removal, user_data);
	} else {
		elements = iter = json_array_get_elements (array);
		while (iter) {
			JsonNode *json_node = (JsonNode *)iter->data;
			if (g_str_equal (node->subscription->source, json_get_string (json_node, "feed_url"))) {
				debug1 (DEBUG_UPDATE, "node: %s", node->subscription->source);
				found = TRUE;
				break;
			}
			iter = g_list_next (iter);
		}
		g_list_free (elements);

		if (!found)			
			feedlist_node_removed (node);
	}				
}
예제 #2
0
파일: node.c 프로젝트: lwindolf/liferea
void
node_reset_update_counter (nodePtr node, GTimeVal *now)
{
	subscription_reset_update_counter (node->subscription, now);

	node_foreach_child_data (node, node_reset_update_counter, now);
}
예제 #3
0
static void
google_subscription_opml_cb (subscriptionPtr subscription, const struct updateResult * const result, updateFlags flags)
{
	AolSourcePtr	gsource = (AolSourcePtr) subscription->node->data;

	subscription->updateJob = NULL;
	
	if (result->data) {
		xmlDocPtr doc = xml_parse (result->data, result->size, NULL);
		if(doc) {		
			xmlNodePtr root = xmlDocGetRootElement (doc);
			
			/* Go through all existing nodes and remove those whose
			   URLs are not in new feed list. Also removes those URLs
			   from the list that have corresponding existing nodes. */
			node_foreach_child_data (subscription->node, aol_source_check_for_removal, (gpointer)root);
			node_foreach_child (subscription->node, aol_source_migrate_node);
						
			opml_source_export (subscription->node);	/* save new feed list tree to disk 
									   to ensure correct document in 
									   next step */

			xpath_foreach_match (root, "/object/list[@name='subscriptions']/object",
			                     aol_source_merge_feed,
			                     (gpointer)gsource);

			opml_source_export (subscription->node);	/* save new feeds to feed list */
						   
			subscription->node->available = TRUE;
			xmlFreeDoc (doc);
		} else { 
			/** @todo The session seems to have expired */
			g_warning ("Unable to parse OPML list from google, the session might have expired.\n");
		}
	} else {
		subscription->node->available = FALSE;
		debug0 (DEBUG_UPDATE, "google_subscription_opml_cb(): ERROR: failed to get subscription list!\n");
	}

	if (!(flags & NODE_SOURCE_UPDATE_ONLY_LIST))
		node_foreach_child_data (subscription->node, node_update_subscription, GUINT_TO_POINTER (0));

}
예제 #4
0
파일: feedlist.c 프로젝트: dmitryvk/liferea
void
feedlist_reset_update_counters (nodePtr node) 
{
	GTimeVal now;
	
	if (!node)
		node = feedlist_get_root ();	
	
	g_get_current_time (&now);
	node_foreach_child_data (node, node_reset_update_counter, &now);
}
예제 #5
0
파일: node.c 프로젝트: lwindolf/liferea
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);
}
예제 #6
0
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_subscription_opml_cb (subscriptionPtr subscription, const struct updateResult * const result, updateFlags flags)
{
	InoreaderSourcePtr	source = (InoreaderSourcePtr) subscription->node->data;

	subscription->updateJob = NULL;
	
	// FIXME: the following code is very similar to ttrss!
	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), "subscriptions"));
			GList		*iter, *elements;
			GSList		*siter;
	
			/* We expect something like this:

			   [{"id":"feed\/http:\/\/rss.slashdot.org\/Slashdot\/slashdot",
                             "title":"Slashdot",
                             "categories":[],
                             "firstitemmsec":"1368112925514",
                             "htmlUrl":"null"},
                           ... 

			   Note that the data doesn't contain an URL. 
			   We recover it from the id field.
			*/
			elements = iter = json_array_get_elements (array);
			/* Add all new nodes we find */
			while (iter) {
				JsonNode *node = (JsonNode *)iter->data;
				
				/* ignore everything without a feed url */
				if (json_get_string (node, "id")) {
					inoreader_source_merge_feed (source, 
					                          json_get_string (node, "id") + 5,	// FIXME: Unescape string!
					                          json_get_string (node, "title"),
					                          json_get_string (node, "id"));
				}
				iter = g_list_next (iter);
			}
			g_list_free (elements);

			/* Remove old nodes we cannot find anymore */
			siter = source->root->children;
			while (siter) {
				nodePtr node = (nodePtr)siter->data;
				gboolean found = FALSE;
				
				elements = iter = json_array_get_elements (array);
				while (iter) {
					JsonNode *json_node = (JsonNode *)iter->data;
					// FIXME: Compare with unescaped string
					if (g_str_equal (node->subscription->source, json_get_string (json_node, "id") + 5)) {
						debug1 (DEBUG_UPDATE, "node: %s", node->subscription->source);
						found = TRUE;
						break;
					}
					iter = g_list_next (iter);
				}
				g_list_free (elements);

				if (!found)			
					feedlist_node_removed (node);
				
				siter = g_slist_next (siter);
			}
			
			opml_source_export (subscription->node);	/* save new feeds to feed list */				   
			subscription->node->available = TRUE;			
			//return;
		} else {
			g_warning ("Invalid JSON returned on Inoreader feed list request! >>>%s<<<", result->data);
		}

		g_object_unref (parser);
	} else {
		subscription->node->available = FALSE;
		debug0 (DEBUG_UPDATE, "inoreader_subscription_cb(): ERROR: failed to get subscription list!");
	}

	if (!(flags & INOREADER_SOURCE_UPDATE_ONLY_LIST))
		node_foreach_child_data (subscription->node, node_update_subscription, GUINT_TO_POINTER (0));
}
예제 #8
0
static void
ttrss_source_subscription_list_cb (const struct updateResult * const result, gpointer user_data, guint32 flags)
{
	subscriptionPtr subscription = (subscriptionPtr) user_data;
	ttrssSourcePtr source = (ttrssSourcePtr) subscription->node->data;

	debug1 (DEBUG_UPDATE,"ttrss_subscription_cb(): %s", result->data);

	subscription->updateJob = NULL;
	
	if (result->data && result->httpstatus == 200) {
		JsonParser	*parser = json_parser_new ();

		if (json_parser_load_from_data (parser, result->data, -1, NULL)) {
			JsonNode	*content = json_get_node (json_parser_get_root (parser), "content");
			JsonArray	*array;
			GList		*iter, *elements;
		
			/* We expect something like this:
			
			[ {"feed_url":"http://feeds.arstechnica.com/arstechnica/everything", 
			   "title":"Ars Technica", 
			   "id":6, 
			   "unread":20, 
			   "has_icon":true, 
			   "cat_id":0, 
			   "last_updated":1287853210}, 
			  {"feed_url":"http://rss.slashdot.org/Slashdot/slashdot", 
			   "title":"Slashdot", 
			   "id":5, 
			   "unread":33, 
			   "has_icon":true, 
			   "cat_id":0, 
			   "last_updated":1287853206}, 
			   [...]
			   

			   Or an error message that could look like this:
	
			      {"seq":null,"status":1,"content":{"error":"NOT_LOGGED_IN"}}

			   */

			if (!content || (JSON_NODE_TYPE (content) != JSON_NODE_ARRAY)) {
				debug0 (DEBUG_UPDATE, "ttrss_subscription_cb(): Failed to get subscription list!");
				subscription->node->available = FALSE;
				return;
			}

			array = json_node_get_array (content);
			elements = iter = json_array_get_elements (array);
			/* Add all new nodes we find */
			while (iter) {
				JsonNode *node = (JsonNode *)iter->data;
				
				/* ignore everything without a feed url */
				if (json_get_string (node, "feed_url")) {
					ttrss_source_merge_feed (source, 
					                         json_get_string (node, "feed_url"),
					                         json_get_string (node, "title"),
					                         json_get_int (node, "id"));
				}
				iter = g_list_next (iter);
			}
			g_list_free (elements);

			/* Remove old nodes we cannot find anymore */
			node_foreach_child_data (source->root, ttrss_source_check_node_for_removal, array);
			
			/* Save new subscription tree to OPML cache file */
			opml_source_export (subscription->node);

			subscription->node->available = TRUE;			
		} else {
			g_warning ("Invalid JSON returned on TinyTinyRSSS request! >>>%s<<<", result->data);
		}

		g_object_unref (parser);
	} else {
		subscription->node->available = FALSE;
		debug0 (DEBUG_UPDATE, "ttrss_subscription_cb(): ERROR: failed to get TinyTinyRSS subscription list!");
	}

	if (!(flags & TTRSS_SOURCE_UPDATE_ONLY_LIST))
		node_foreach_child_data (subscription->node, node_update_subscription, GUINT_TO_POINTER (0));	
}
예제 #9
0
static void
theoldreader_subscription_cb (subscriptionPtr subscription, const struct updateResult * const result, updateFlags flags)
{
	TheOldReaderSourcePtr	source = (TheOldReaderSourcePtr) subscription->node->data;

	debug1 (DEBUG_UPDATE,"theoldreader_subscription_cb(): %s", result->data);
	
	// FIXME: the following code is very similar to ttrss!
	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), "subscriptions"));
			GList		*iter, *elements;
			GSList		*siter;
		
			/* We expect something like this:

			   [{"id":"feed/51d49b79d1716c7b18000025",
                             "title":"LZone",
                             "categories":[],
                             "sortid":"51d49b79d1716c7b18000025",
                             "firstitemmsec":"1371403150181",
                             "url":"http://lzone.de/rss.xml",
                             "htmlUrl":"http://lzone.de",
                             "iconUrl":"http://s.yeoldereader.com/system/uploads/feed/picture/5152/884a/4dce/57aa/7e00/icon_0a6a.ico"},
                           ... 
			*/
			elements = iter = json_array_get_elements (array);
			/* Add all new nodes we find */
			while (iter) {
				JsonNode *node = (JsonNode *)iter->data;
				
				/* ignore everything without a feed url */
				if (json_get_string (node, "url")) {
					theoldreader_source_merge_feed (source, 
					                                json_get_string (node, "url"),
					                                json_get_string (node, "title"),
					                                json_get_string (node, "id"));
				}
				iter = g_list_next (iter);
			}
			g_list_free (elements);

			/* Remove old nodes we cannot find anymore */
			siter = source->root->children;
			while (siter) {
				nodePtr node = (nodePtr)siter->data;
				gboolean found = FALSE;
				
				elements = iter = json_array_get_elements (array);
				while (iter) {
					JsonNode *json_node = (JsonNode *)iter->data;
					if (g_str_equal (node->subscription->source, json_get_string (json_node, "url"))) {
						debug1 (DEBUG_UPDATE, "node: %s", node->subscription->source);
						found = TRUE;
						break;
					}
					iter = g_list_next (iter);
				}
				g_list_free (elements);

				if (!found)			
					feedlist_node_removed (node);
				
				siter = g_slist_next (siter);
			}
			
			opml_source_export (subscription->node);	/* save new feeds to feed list */				   
			subscription->node->available = TRUE;			
			//return;
		} else {
			g_warning ("Invalid JSON returned on TheOldReader request! >>>%s<<<", result->data);
		}

		g_object_unref (parser);
	} else {
		subscription->node->available = FALSE;
		debug0 (DEBUG_UPDATE, "theoldreader_subscription_cb(): ERROR: failed to get subscription list!");
	}

	if (!(flags & THEOLDREADER_SOURCE_UPDATE_ONLY_LIST))
		node_foreach_child_data (subscription->node, node_update_subscription, GUINT_TO_POINTER (0));
}
예제 #10
0
static void
theoldreader_subscription_cb (subscriptionPtr subscription, const struct updateResult * const result, updateFlags flags)
{
	TheOldReaderSourcePtr	source = (TheOldReaderSourcePtr) subscription->node->data;

	debug1 (DEBUG_UPDATE,"theoldreader_subscription_cb(): %s", result->data);

	subscription->updateJob = NULL;
	
	// FIXME: the following code is very similar to ttrss!
	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), "subscriptions"));
			GList		*iter, *elements, *citer, *celements;
			GSList		*siter;

			/* We expect something like this:

			   [{"id":"feed/51d49b79d1716c7b18000025",
                             "title":"LZone",
                             "categories":[{"id":"user/-/label/myfolder","label":"myfolder"}],
                             "sortid":"51d49b79d1716c7b18000025",
                             "firstitemmsec":"1371403150181",
                             "url":"http://lzone.de/rss.xml",
                             "htmlUrl":"http://lzone.de",
                             "iconUrl":"http://s.yeoldereader.com/system/uploads/feed/picture/5152/884a/4dce/57aa/7e00/icon_0a6a.ico"},
                           ... 
			*/
			elements = iter = json_array_get_elements (array);
			/* Add all new nodes we find */
			while (iter) {
				JsonNode *categories, *node = (JsonNode *)iter->data;
				nodePtr folder = NULL;

				/* Check for categories, if there use first one as folder */
				categories = json_get_node (node, "categories");
				if (categories && JSON_NODE_TYPE (categories) == JSON_NODE_ARRAY) {
					citer = celements = json_array_get_elements (json_node_get_array (categories));
					while (citer) {
						const gchar *label = json_get_string ((JsonNode *)citer->data, "label");
						if (label) {
							folder = node_source_find_or_create_folder (source->root, label, label);

							/* Store category id also for folder (needed when subscribing new feeds) */
							g_hash_table_insert (source->folderToCategory, g_strdup (folder->id), g_strdup (label));

							break;
						}
						citer = g_list_next (citer);
					}
					g_list_free (celements);
				}
				
				/* ignore everything without a feed url */
				if (json_get_string (node, "url")) {
					theoldreader_source_merge_feed (source, 
					                                json_get_string (node, "url"),
					                                json_get_string (node, "title"),
					                                json_get_string (node, "id"),
									folder);
				}
				iter = g_list_next (iter);
			}
			g_list_free (elements);

			/* Remove old nodes we cannot find anymore */
			node_foreach_child_data (source->root, theoldreader_source_check_node_for_removal, array);
			
			/* Save new subscription tree to OPML cache file */
			opml_source_export (subscription->node);

			subscription->node->available = TRUE;			
		} else {
			g_warning ("Invalid JSON returned on TheOldReader request! >>>%s<<<", result->data);
		}

		g_object_unref (parser);
	} else {
		subscription->node->available = FALSE;
		debug0 (DEBUG_UPDATE, "theoldreader_subscription_cb(): ERROR: failed to get subscription list!");
	}

	if (!(flags & NODE_SOURCE_UPDATE_ONLY_LIST))
		node_foreach_child_data (subscription->node, node_update_subscription, GUINT_TO_POINTER (0));
}
예제 #11
0
static void
default_source_update (nodePtr node)
{	
	node_foreach_child_data (node, node_update_subscription, GUINT_TO_POINTER (0));
}