Tuesday, March 29, 2011 at 1:07 AM.

river2Suite.newItem

on newItem (adrxitem, adrfeed) {
	<<Changes
		<<3/27/11; 12:50:34 PM by DW
			<<Add the url of this feed to the adrdata^.stats.updatedFeeds table. 
		<<2/5/10; 12:51:29 PM by DW
			<<When decoding strings, set flDecodeHexEntities true. Previously it was unspecified, and defaulted false. 
		<<2/3/10; 10:30:55 AM by DW
			<<Pictures only come from items with pictures in the enclosure element of an item. This basically means the AP and AFP feeds get sorted into the Pictures menu item in River2 and all others show up in the main list. The purpose was to get the huge number of AFP pictures out of the way in the main stream, and it still accomplishes this goal.
		<<2/1/10; 5:09:01 PM by DW
			<<Come up with a hack so that WordPress "gravatars" -- which are transmitted via media:content, are not seen as pictures, while Flickr pictures, which use the same element are picked up. The trick is that Flickr includes a "type" attribute with a value of "image/jpeg" and WordPress does not include a type element. This could easily break, that's why it's a hack. And someone else's gravatar might have a JPEG image, or someday we may want to handle PNG images. That's why it would be better to have a simple way for an item to include a gravatar. But for now this will have to do.
			<<I wrote this up here:
				<<http://www.scripting.com/stories/2010/02/01/caseStudyInExtendingRss.html
		<<12/16/09; 10:47:04 AM by DW
			<<Get images from media:content items, which makes River2 work as a photo catcher for Flickr feeds.
		<<9/9/09; 7:06:30 AM by DW
			<<For podcasts, add a flPodcast boolean to the type table; for photos, flPhoto. Also, call initRiverItem for each new item. We weren't doing this. Ooops. :-)
		<<9/7/09; 9:15:21 PM by DW
			<<Pull thumbnails out of xitems, sort pictures into separate calendar structure.
		<<8/20/09; 10:53:56 AM by DW
			<<Add a reference to each item to the calendar for its feed.
		<<8/17/09; 10:36:10 AM by DW
			<<Add podcasts to the podcasts calendar structure.
		<<6/16/09; 11:25:22 AM by DW
			<<Created. Called when a new item arrives.
	local (adrdata = river2suite.init (), now = clock.now (), feedurl = nameof (adrfeed^));
	local (adrday = mainresponder.calendar.getdayaddress (@adrdata^.river, now));
	local (adrriveritem = @adrday^.[string.padwithzeros (adrdata^.stats.ctItems++, 7)]);
	new (tabletype, adrriveritem);
	river2Suite.initRiverItem (adrriveritem); //9/9/09 by DW
	adrriveritem^.feedUrl = feedurl; //link the item back to the feed it came from
	on decode (s) {
		return (xml.entitydecode (s, flAlphaEntities:true, flDecodeHexEntities:true))};
	on getoptionalstringitem (nameitem) {
		try {
			adrriveritem^.[nameitem] = decode (xml.getvalue (adrxitem, nameitem))}
		else {
			adrriveritem^.[nameitem] = ""}};
	on addItemToCalendar (adrriveritem, adrcal) {
		local (adrday = mainresponder.calendar.getdayaddress (adrcal, now));
		adrday^.[nameof (adrriveritem^)] = now};
	getoptionalstringitem ("title");
	getoptionalstringitem ("link");
	getoptionalstringitem ("description");
	getoptionalstringitem ("comments");
	bundle { //pubdate
		try {
			adrriveritem^.pubDate = date (xml.getvalue (adrxitem, "pubDate"))}
		else {
			adrriveritem^.pubDate = now}};
	bundle { //enclosure
		try {
			local (url, type, length, flenclosure);
			bundle { //get url, type and length or fail if not able to, 12/16/09 by DW
				try { //see if you can get it from an enclosure element
					local (adrenclosure = xml.getaddress (adrxitem, "enclosure"));
					url = decode (xml.getattributevalue (adrenclosure, "url"));
					type = decode (xml.getattributevalue (adrenclosure, "type"));
					length = decode (xml.getattributevalue (adrenclosure, "length"));
					flenclosure = true} //2/3/10 by DW
				else { //see if you can get it from a media:content element
					local (adrcontent = xml.getaddress (adrxitem, "content"));
					local (namespace = decode (xml.getattributevalue (adrcontent, "namespace")));
					if namespace != "media:" {
						scripterror ("Namespace for content element must be \"media:\"")};
					bundle { //must have an attribute named "type" with value "image/jpeg" -- 2/1/10 by DW
						local (typeatt = decode (xml.getattributevalue (adrcontent, "type")));
						if typeatt != "image/jpeg" {
							scripterror ("Media content type must be \"image/jpeg.\"")}};
					url = decode (xml.getattributevalue (adrcontent, "url"));
					tcp.httpGetTypeLength (url, @type, @length, 5);
					flenclosure = false}}; //2/3/10 by DW
			new (tabletype, @adrriveritem^.enclosure);
			adrriveritem^.enclosure.url = url;
			adrriveritem^.enclosure.type = type;
			adrriveritem^.enclosure.length = length;
			adrdata^.stats.ctEnclosures++;
			adrdata^.stats.whenLastEnclosure = now;
			bundle { //add podcasts to the podcast table, 8/17/09 by DW
				local (flpodcast = false);
				if flenclosure { //2/3/10 by DW
					if string.lower (url) endswith ".mp3" {
						flpodcast = true};
					if (type == "video/mpeg") or (type == "video/quicktime") or (type == "audio/mpeg") {
						flpodcast = true};
					if flpodcast {
						addItemToCalendar (adrriveritem, @adrdata^.enclosures.podcasts);
						adrriveritem^.type.flPodcast = true}}}; //9/8/09 by DW
			bundle { //add pictures to the pictures table, 9/7/09 by DW
				local (flpic = false);
				if flenclosure { //2/3/10 by DW
					if (string.lower (url) endswith ".gif") or (string.lower (url) endswith ".jpg") or (string.lower (url) endswith ".jpeg") {
						flpic = true};
					if (type == "image/jpeg") or (type == "image/gif") or (type == "image/png") {
						flpic = true};
					if flpic {
						addItemToCalendar (adrriveritem, @adrdata^.enclosures.pictures);
						adrriveritem^.type.flPhoto = true}}}}}; //9/8/09 by DW
	bundle { //thumbnail, 9/7/09 by DW
		try {
			local (adrthumbnail = xml.getaddress (adrxitem, "thumbnail"));
			local (namespace = decode (xml.getattributevalue (adrthumbnail, "namespace")));
			if namespace == "media:" {
				local (height = number (xml.getattributevalue (adrthumbnail, "height")));
				local (width = number (xml.getattributevalue (adrthumbnail, "width")));
				local (url = decode (xml.getattributevalue (adrthumbnail, "url")));
				new (tabletype, @adrriveritem^.thumbnail);
				adrriveritem^.thumbnail.height = height;
				adrriveritem^.thumbnail.width = width;
				adrriveritem^.thumbnail.url = url}}};
	bundle { //permalink
		try {
			local (adrguid = xml.getaddress (adrxitem, "guid"), isPermaLink=true);
			try {
				isPermaLink = boolean (decode (xml.getattributevalue (adrguid, "isPermaLink")))};
			if isPermaLink {
				adrriveritem^.permalink = decode (adrguid^)}};
		if not defined (adrriveritem^.permalink) {
			adrriveritem^.permalink = ""}};
	addItemToCalendar (adrriveritem, @adrfeed^.calendar); //8/20/09 by DW
	adrfeed^.stats.ctItems++;
	adrfeed^.stats.whenLastNewItem = now;
	bundle { //add the url of this feed to the adrdata^.stats.updatedFeeds table -- 3/27/11 by DW
		local (adr = @adrdata^.stats.updatedFeeds.[feedurl]);
		if defined (adr^) {
			adr^++}
		else {
			adr^ = 1}};
	bundle { //callbacks
		local (adrscript);
		for adrscript in @adrdata^.callbacks.newItem {
			while typeof (adrscript^) == addresstype {
				adrscript = adrscript^};
			try {adrscript^ (adrriveritem, adrfeed, adrxitem)}}}};
bundle { //test code
	newItem (@scratchpad.feed.items.["005"], @config.river2.feeds.["http://evespeeves.wordpress.com/feed/"])}



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.