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.