Thursday, March 31, 2011 at 1:05 AM.

river2Suite.viewJsonNews

on viewJsonNews (adrcal=nil, version=1) {
	<<Changes
		<<3/30/11; 6:54:29 AM by DW
			<<Respect the new user-level maxRiverItems pref.
		<<3/27/11; 12:19:20 PM by DW
			<<Pass adrdata^.prefs.maxDaysNews to mainresponder.calendar.visitReverseChronologic to limit the number of days we're willing to go back in time.
		<<12/18/10; 7:06:55 PM by DW
			<<New optional param, version, defaults to 1 -- the original format. In version 2, each "updatedFeed" has exactly one item it. You'll never see a list where an item could be. This means the info is repeated, so the file is a little fatter. You should still group updates from a single feed that happened at the same time. But now that grouping is not reflected in the structure. 
		<<12/7/10; 10:15:28 AM by DW
			<<Add a docs value to the metadata section, pointing to a Scripting News article that explains what's going on here.
		<<12/5/10; 3:07:42 PM by DW
			<<Return a JSON representation of the news page.
	local (pta = html.getpagetableaddress (), adrdata = river2suite.init (), startticks = clock.ticks (), maxitems);
	local (flhomepage = true, ct = 0, errorstring = "", flcache = true);
	local (xtable, adrUpdatedFeedstable, adrCurrentUpdatedFeed, lastFeedUrl, adrxitem);
	bundle { //set up xtable
		new (tabletype, @xtable);
		adrUpdatedFeedstable = xml.addtable (@xtable, "updatedFeeds");
		adrCurrentUpdatedFeed = nil; //indicate that it hasn't been set yet
		lastFeedUrl = ""}; //force the first item to create a new updated feed table
	bundle { //set maxitems, 3/29/11 by DW
		maxitems = adrdata^.prefs.maxItemsHomePage;
		if pta^.adruser != nil {
			if pta^.adruser^.prefs.maxRiverItems < maxitems {
				maxitems = pta^.adruser^.prefs.maxRiverItems}}};
	on visit (adritem) {
		if typeof (adritem^) != tabletype { //for processing podcasts and picture calender items
			local (name = nameof (adritem^));
			local (adrday = mainresponder.calendar.getdayaddress (@adrdata^.river, adritem^));
			adritem = @adrday^.[name]};
		<<bundle //check type and flags, possibly return, 9/9/09 by DW
			<<if defined (adritem^.type)
				<<if flhomepage //9/15/09 by DW
					<<if not adrdata^.prefs.flPodcastsOnHomePage
						<<if adritem^.type.flPodcast
							<<return (true)
					<<if not adrdata^.prefs.flPhotosOnHomePage
						<<if adritem^.type.flPhoto
							<<return (true)
		bundle { //don't display items from feeds that have been unsubbed, 9/15/09 by DW
			if not defined (adrdata^.feeds.[adritem^.feedurl]) { //9/15/09 by DW
				return (true)}};
		bundle { //display the item in a try, 1/2/10 by DW
			try {
				local (title = adritem^.title, feedurl = adritem^.feedurl, link, flTitleEndsWithPunc);
				local (flduplicatedescription = title == adritem^.description); //10/1/10 by DW
				bundle { //set flTitleEndsWithPunc, 5/20/10 by DW
					local (s = string.trimwhitespace (title), x = sizeof (s));
					if x > 0 {
						local (ch = s [x]);
						flTitleEndsWithPunc = (ch == '!') or (ch == '?')}
					else {
						flTitleEndsWithPunc = false}};
				local (itemnum = number (nameof (adritem^)), itemname = "item" + itemnum);
				local (namelink = "<a name=\"" + itemname + "\"></a>");
				if pta^.adruser != nil { //12/2/09 by DW
					if not defined (pta^.adruser^.feeds.[feedurl]) { //user isn't following this feed
						return (true)}};
				local (adrfeed = @adrdata^.feeds.[feedurl]);
				if not defined (adrfeed^) { //8/17/09 by DW -- feed has been deleted
					return (true)};
				bundle { //if feedurl changed, add a row that has the feed's name
					if (feedurl != lastfeedurl) or (version >= 2) {
						local (adrfeedinfo = @adrfeed^.feedinfo);
						
						adrCurrentUpdatedFeed = xml.addtable (adrUpdatedFeedstable, "updatedFeed");
						xml.addvalue (adrCurrentUpdatedFeed, "feedTitle", adrfeedinfo^.title);
						xml.addvalue (adrCurrentUpdatedFeed, "feedUrl", feedurl);
						xml.addvalue (adrCurrentUpdatedFeed, "websiteUrl", adrfeedinfo^.link);
						xml.addvalue (adrCurrentUpdatedFeed, "whenLastUpdate", date.netstandardstring (timeCreated (adritem)));
						
						lastfeedurl = feedurl}};
				bundle { //set adrxitem
					adrxitem = xml.addtable (adrCurrentUpdatedFeed, "item");
					xml.addvalue (adrxitem, "id", nameof (adritem^));
					xml.addvalue (adrxitem, "title", adritem^.title);
					xml.addvalue (adrxitem, "link", adritem^.link);
					xml.addvalue (adrxitem, "permaLink", adritem^.permalink);
					xml.addvalue (adrxitem, "pubDate", date.netstandardstring (adritem^.pubDate))};
				bundle { //set body
					if (not defined (adritem^.body)) or (not flcache) {
						if flduplicatedescription { //10/1/10 by DW
							adritem^.body = ""}
						else {
							adritem^.body = searchengine.stripmarkup (adritem^.description)};
						if sizeof (adritem^.body) > adrdata^.prefs.maxBodyLength {
							adritem^.body = string.mid (adritem^.body, 1, adrdata^.prefs.maxBodyLength);
							while adritem^.body [sizeof (adritem^.body)] != " " {
								adritem^.body = string.delete (adritem^.body, sizeof (adritem^.body), 1)};
							adritem^.body = string.delete (adritem^.body, sizeof (adritem^.body), 1);
							adritem^.body = adritem^.body + "..."}};
					xml.addvalue (adrxitem, "body", adritem^.body)};
				bundle { //enclosure
					if defined (adritem^.enclosure) {
						local (adrxenclosure = xml.addtable (adrxitem, "enclosure"));
						xml.addvalue (adrxenclosure, "url", adritem^.enclosure.url);
						xml.addvalue (adrxenclosure, "type", adritem^.enclosure.type);
						xml.addvalue (adrxenclosure, "length", adritem^.enclosure.length)}};
				bundle { //thumbnail
					if defined (adritem^.thumbnail) { //9/7/09 by DW
						local (adrxthumbnail = xml.addtable (adrxitem, "thumbnail"));
						xml.addvalue (adrxthumbnail, "url", adritem^.thumbnail.url);
						xml.addvalue (adrxthumbnail, "width", adritem^.thumbnail.width);
						xml.addvalue (adrxthumbnail, "height", adritem^.thumbnail.height)}};
				bundle { //comments
					if sizeof (adritem^.comments) > 0 {
						xml.addvalue (adrxitem, "comments", adritem^.comments)}}}
			else {
				return (false)}};
		return (++ct <= maxitems)};
	if adrcal == nil {
		adrcal = @adrdata^.river};
	mainresponder.calendar.visitReverseChronologic (adrcal, @visit, maxDays:adrdata^.prefs.maxDaysNews); //3/27/11 by DW
	bundle { //add metadata
		local (adrxmeta = xml.addtable (@xtable, "metadata"), now = clock.now ());
		xml.addvalue (adrxmeta, "docs", "http://scripting.com/stories/2010/12/06/innovationRiverOfNewsInJso.html"); //12/7/10 by DW
		xml.addvalue (adrxmeta, "whenGMT", date.netstandardstring (now));
		xml.addvalue (adrxmeta, "whenLocal", now + " Eastern");
		xml.addvalue (adrxmeta, "version", version); //12/18/10 by DW
		bundle { //add a secs element
			local (s = string (double (clock.ticks () - startticks) / 60));
			local (lod = string.nthfield (s, ".", 1));
			local (rod = string.nthfield (s, ".", 2) + "00");
			if sizeof (rod) > 3 {
				rod = string.mid (rod, 1, 3)};
			xml.addvalue (adrxmeta, "secs", lod + "." + rod)}};
	<<scratchpad.xtable = xtable //debugging
	return (json.decompile (@xtable))};
bundle { //test code
	local (pt);
	new (tabletype, @pt); pt.adruser = nil;
	html.setpagetableaddress (@pt);
	local (tc = clock.ticks ());
	webbrowser.displaytext (viewJsonNews ());
	dialog.alert (clock.ticks () - tc)}



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.