Tuesday, April 12, 2011 at 1:05 AM.

scripting2Suite.server.buildRss

on buildRss (username, flupload=true) {
	<<Changes
		<<4/11/11; 6:52:44 PM by DW
			<<Call callbacks.
		<<12/22/10; 6:48:39 PM by DW
			<<Write out rss.json and rss.js based on the XML we generate.
		<<9/22/10; 11:23:43 AM by DW
			<<Do a rssCloud ping when the feed updates.
		<<7/10/10; 5:30:17 AM by DW
			<<For version, use the version of Scripting2, not the version of the OPML Editor (which almost never changes, and isn't very relevant).
		<<7/10/10; 5:25:03 AM by DW
			<<RSS feeds now take their title, link and description from the blog prefs if they haven't been set independently (right now there's no UI to set them).
		<<7/8/10; 7:51:37 AM by DW
			<<Don't do glossary substitutions on the whole feed, just do them on the description.
		<<6/25/10; 8:25:31 PM by DW
			<<Use our visitReverseChronologic routine to exclude stories that aren't in the chronology.
		<<6/14/10; 5:59:17 PM by DW
			<<Add support for enclosures.
		<<6/11/10; 8:12:54 AM by DW
			<<Add optional flupload param, so we can debug without breaking the feed.
		<<7/18/09; 5:06:22 PM by DW
			<<Add <cloud> element.
		<<9/13/07; 7:53:08 PM by DW
			<<The default RSS feed is the new one, with the last 15 posts, not just today's posts.
		<<9/7/07; 3:14:43 PM by DW
			<<Also write a new form of RSS with the last 15 posts, not just today's posts.
		<<11/14/03; 11:23:08 AM by DW
			<<We were sending the archive copies to the wrong folder. Two days will be in the wrong folder in the archive on scripting.com, in 2003, instead of rssArchive/2003. Maybe we can remember to move them.
		<<11/12/03; 8:03:11 AM by DW
			<<Created.
	local (adrdata = scripting2Suite.initUser (username), startticks = clock.ticks (), adrday, archivedate);
	local (now = clock.now (), day, month, year, hour, minute, second);
	date.get (now, @day, @month, @year, @hour, @minute, @second);
	local (pubdate = date.set (day, month, year, 0, 0, 0));
	local (xmltext = "");
	bundle { //generate xmltext
		local (indentlevel = 0);
		on add (s) {
			xmltext = xmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n");};
		on encode (s) {
			if system.environment.isMac { //02/22/2001 JES: convert to Latin text
				return (xml.entityEncode (latinToMac.macToLatin (s), true))}
			else {
				return (xml.entityEncode (s, true))}};
		on getTtl () {
			local (ctminutes = (number (now) - number (adrdata^.stats.whenLastUpdate)) / 60);
			if ctminutes < 60 { //one hour since last update
				return (15)};
			if ctminutes < 180 { //three hours
				return (60)};
			return (480)};
		bundle { //add header elements
			local (headerdata, programversion = scripting2Suite.getProgramName ());
			scripting2Suite.server.getRssHeaderData (username, @headerdata); //7/10/10 by DW
			add ("<?xml version=\"1.0\"?>");
			add ("<!-- RSS generated by " + programversion + " on " + date.netstandardstring (now) + " -->");
			add ("<rss version=\"2.0\" xmlns:scripting2=\"http://scripting2.com/namespace.html\">"); indentlevel++;
			add ("<channel>"); indentlevel++;
			add ("<title>" + encode (headerdata.title) + "</title>");
			add ("<link>" + encode (headerdata.link) + "</link>");
			add ("<description>" + encode (headerdata.description) + "</description>");
			add ("<language>" + headerdata.language + "</language>");
			add ("<copyright>" + "Copyright " + date.year () + " " + encode (headerdata.copyrightHolder) + "</copyright>");
			add ("<pubDate>" + date.netstandardstring (pubdate) + "</pubDate>");
			add ("<lastBuildDate>" + date.netstandardstring (now) + "</lastBuildDate>");
			add ("<docs>" + scripting2Suite.data.urls.rssDocs + "</docs>");
			add ("<generator>" + encode (programversion) + "</generator>");
			add ("<managingEditor>" + encode (headerdata.managingEditor) + "</managingEditor>");
			add ("<webMaster>" + encode (headerdata.webmaster) + "</webMaster>");
			bundle { //add <cloud>, 7/18/09 by DW
				add ("<cloud domain=\"rpc.rsscloud.org\" port=\"5337\" path=\"/rsscloud/pleaseNotify\" registerProcedure=\"\" protocol=\"http-post\" />")};
			add ("<ttl>" + getTtl () + "</ttl>")};
		bundle { //add items
			local (ctitems = 0);
			on visit (adrstory) {
				if ctitems >= adrdata^.prefs.ctStoriesOnHomePage {
					return (false)};
				add ("<item>"); indentlevel++;
				add ("<title>" + encode (adrstory^.title) + "</title>");
				
				<<op.insert (adrstory^.title, up); op.insert (adrstory, right); op.go (left, 1)
				
				bundle { //link, guid
					<<local (day, month, year, hour, minute, second)
					<<date.get (adrstory^.when, @day, @month, @year, @hour, @minute, @second)
					<<month = string.padwithzeros (month, 2)
					<<day = string.padwithzeros (day, 2)
					urlstory = adrstory^.url;
					add ("<link>" + encode (urlstory) + "</link>");
					add ("<guid>" + encode (urlstory) + "</guid>");
					if adrdata^.prefs.flDisqusComments { //7/4/10 by DW
						add ("<comments>" + encode (urlstory) + "#disqus_thread</comments>")}};
				bundle { //add description
					add ("<description>"); indentlevel++;
					add (encode (scripting2Suite.server.getPlainStoryText (adrstory, indentlevel, @adrdata^.prefs.glossary)));
					add ("</description>"); indentlevel--};
				add ("<pubDate>" + date.netstandardstring (adrstory^.postDate) + "</pubDate>");
				add ("<scripting2:source>" + encode (adrstory^.urlOpml) + "</scripting2:source>");
				bundle { //enclosure, 6/14/10 by DW
					if scripting2Suite.server.getEnclosure (adrstory) {
						add ("<enclosure url=\"" + adrstory^.enclosure.url + "\" length=\"" + adrstory^.enclosure.length + "\" type=\"" + adrstory^.enclosure.type + "\" />")}};
				<<bundle //enclosure, 3/5/08; 7:12:53 PM by DW
					<<if defined (adrstory^.enclosure)
						<<add ("<enclosure url=\"" + adrstory^.enclosure.url + "\" length=\"" + adrstory^.enclosure.length + "\" type=\"" + adrstory^.enclosure.type + "\" />")
				add ("</item>"); indentlevel--;
				ctitems++;
				return (true)};
			scripting2Suite.server.visitReverseChronologic (@adrdata^.calendar, @visit)};
			<<bundle //old code
				<<local (adrstory, storiestable, s = "", label, urlstory)
				<<scripting2Suite.getStories (username, @storiestable, adrdata^.prefs.ctStoriesOnHomePage)
				<<for adrstory in @storiestable
					<<add ("<item>"); indentlevel++
					<<add ("<title>" + encode (adrstory^.title) + "</title>")
					<<bundle //link, guid
						<<local (label = scripting2Suite.getStoryLabel (adrstory^.title))
						<<local (day, month, year, hour, minute, second)
						<<date.get (adrstory^.when, @day, @month, @year, @hour, @minute, @second)
						<<month = string.padwithzeros (month, 2)
						<<day = string.padwithzeros (day, 2)
						<<urlstory = "http://scripting.com/stories/" + year + "/" + month + "/" + day + "/" + label + ".html"
						<<add ("<link>" + encode (urlstory) + "</link>")
						<<add ("<guid>" + encode (urlstory) + "</guid>")
						<<add ("<comments>" + encode (urlstory) + "#disqus_thread</comments>")
					<<add ("<description>" + encode (adrstory^.body) + "</description>")
					<<add ("<pubDate>" + date.netstandardstring (adrstory^.when) + "</pubDate>")
					<<bundle //enclosure, 3/5/08; 7:12:53 PM by DW
						<<if defined (adrstory^.enclosure)
							<<add ("<enclosure url=\"" + adrstory^.enclosure.url + "\" length=\"" + adrstory^.enclosure.length + "\" type=\"" + adrstory^.enclosure.type + "\" />")
					<<add ("</item>"); indentlevel--
		add ("</channel>"); indentlevel--;
		add ("</rss>"); indentlevel--};
		<<bundle //string substitutions, 4/13/07; 1:08:53 PM by DW
			<<xmltext = scripting2Suite.server.glossarySubstitution (@adrdata^.prefs.glossary, xmltext)
			<<xmltext = scripting2Suite.server.glossarySubstitution (@scripting2Suite.data.systemGlossary, xmltext)
	bundle { //save the file
		if flupload {
			adrdata^.stats.urlRSS = scripting2Suite.writeStaticFile (username, scripting2Suite.data.paths.rss, xmltext);
			scripting2Suite.writeStaticFile (username, "rssArchive/" + file.getdatepath ("/", archivedate, false) + ".xml", xmltext);
			scripting2suite.server.pingRssCloud (adrdata^.stats.urlRSS); //9/22/10 by DW
			scripting2Suite.server.buildRssJson (xmltext, username); //12/22/10 by DW
			bundle { //call callbacks, 4/11/11 by DW
				local (adrscript);
				for adrscript in @adrdata^.callbacks.buildRss {
					while typeof (adrscript^) == addresstype {
						adrscript = adrscript^};
					try {adrscript^ (xmltext)}}};
			bundle { //logging, 7/2/10 by DW
				local (s = "Updated <a href=\"" + adrdata^.stats.urlRSS + "\">RSS feed</a> for user \"" + username + ".\"");
				scripting2Suite.server.addToLog (scripting2Info.name, "RSS build", s, startticks)}}}};
bundle { //test code
	new (outlinetype, @scratchpad.rssoutline); target.set (@scratchpad.rssoutline);
	buildRss ("davewiner")}



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.