Monday, November 08, 2010 at 12:05 AM.

system.verbs.builtins.radio.weblog.publish

on publish (adrblog=radio.weblog.init (), catname=nil, d=nil) {
	<<Changes:
		<<9/3/02; 3:42:52 PM by LL
			<<Added support for weekly weblog archives.
		<<8/26/02; 10:39:24 PM by LL
			<<Added support for monthly weblog archives.
		<<8/14/02; 12:40:43 AM by JES
			<<Always add the home page to the table at system.temp.radio.pingAfterUpstream. Fixes a bug where if the weblogs.com ping is turned off in the prefs, then the local RCS never gets a ping. Checking the pref here was redundant anyway, since it's checked in radio.thread.agents.pingWeblogsCom.
		<<6/5/02; 12:42:07 PM by DW
			<<Every time the user publishes, we track the update in a new table at weblogData.stats.hourlyUpdateCounts.
		<<2/13/02; 12:19:00 PM by JES
			<<Don't add the #categoryName directive to the index file for categories.
		<<2/12/02; 5:13:19 PM by JES
			<<When checking to see if a value was specified for the optional d parameter, check typeOf (d) == unknownType, instead of checking d == nil. Fixes a bug where archive pages are sometimes not rendered when they should be.
		<<2/1/02; 3:01:31 PM by JES
			<<When publishing a weblog page, set adrfile^.upstream.whenLastUploaded to date (0), instead of changing the mod-date of the file itself.
		<<1/21/02; 8:05:39 AM by DW
			<<Add a sub-table to system.temp.radio.pingAfterUpstream, indexed on the file, containing name and url of the weblog. Handled by a new agent script that watches for this table being non-empty.
			<<I made it work for both the home page and category pages. One system for notifying Weblogs.Com, flowing through a single agent script. Easy to get control of. Extra benefit, it makes upstreaming report quicker on the Events page.
		<<12/20/01; 1:51:08 AM by JES
			<<Use file.writeTextFile to write the files, instead of file.writeWholeFile. This also eliminates a bunch of calculation of line-endings and Mac type/creator codes. More factoring to be done here still.
		<<12/19/01; 3:05:38 PM by JES
			<<Uncomment logging of Weblog Publish events.
		<<12/19/01; 11:19:39 AM by JES
			<<Commented out logging of Weblog Publish events.
		<<12/18/01; 12:48:41 AM by JES
			<<Revive the Weblog Publish event for the Events log.
		<<12/13/01; 5:19:50 PM by JES
			<<On MacOS X, write text files with a type of '    ' and a creator of 'text'.
		<<12/7/01; 2:46:31 AM by JES
			<<Fixed macro error: CanŐt find a sub-table named""
		<<12/6/01; 11:11:51 PM by JES
			<<If adrcat^.flRenderHtml is not defined, initialize it to false. If adrcat^.flRenderHtml is false, do nothing.
		<<11/19/01; 3:08:59 PM by JES
			<<If this is www/index.txt -- the weblog home page, add an #flSystemPage true directive to suppress the Edit This Page button.
		<<11/13/01; 5:14:45 PM by JES
			<<Complete rewrite. This is the bottleneck for creating/updating files in the www folder, which render weblog content, both for the main weblog and archive pages, and for the category index and archive pages.
			<<Returns the path to the .txt file on disk.
			<<Parameters
				<<adrblog -- the address of the weblog table in the odb
				<<catname -- the name of the category to publish; if nil, we're publishing a weblog page
				<<d -- the date of the archive page to publish; if nil, we're publishing the index page
			<<bundle //old code
				<<local (startticks = clock.ticks ())
				<<local (filepath = adrblog^.prefs.homePageFilePath, adrcat)
				<<local (flArchivePage = (d != nil), archiveFtpPath)
				<<local (minDate = date.set (1, 1, 1904, 0, 0, 0), maxDate = date.set (1, 1, 2040, 0, 0, 0))
				<<bundle //set filepath, adrcat
					<<if flArchivePage //PBS 02/22/01: set the filepath for an archive day
						<<local (extension = "")
						<<bundle //get the extension from the home page filename
							<<if filepath endsWith "/" //default to .html
								<<extension = ".html"
							<<else
								<<local (homePageFileName = string.nthField (filepath, "/", string.countFields (filepath, "/")))
								<<if homePageFileName contains "."
									<<extension = "." + string.nthField (homePageFileName, ".", string.countFields (homePageFileName, "."))
						<<filepath = string.popSuffix (filepath, '/')
						<<local (day, month, year, hour, minute, second)
						<<date.get (d, @day, @month, @year, @hour, @minute, @second)
						<<archiveFtpPath = year + "/" + string.padWithZeros (month, 2) + "/" + string.padWithZeros (day, 2) + extension
						<<filepath = filepath + "/" + archiveFtpPath
						<<minDate = date.set (day, month, year, 0, 0, 0) //12 a.m.
						<<maxDate = date.set (day, month, year, 23, 59, 59) //11:59:59 p.m.
					<<if catname != nil
						<<local (folderpath = string.popTrailingFilename (filepath))
						<<adrcat = @adrblog^.categories.[catname]
						<<filepath = folderpath + "categories/" + adrcat^.filename + ".html"
						<<if catname != nil //set the htmlUrl
							<<adrcat^.htmlUrl = user.playlist.prefs.wwwUpstreamFolderUrl + filepath
				<<local (f) //the local file to write to
				<<bundle //set f
					<<local (pc = file.getpathchar ())
					<<local (partialpath = string.replaceall (filepath, "/", pc))
					<<if (partialpath beginswith pc) and (user.radio.prefs.wwwfolder endswith pc)
						<<partialpath = string.delete (partialpath, 1, 1)
					<<f = user.radio.prefs.wwwfolder + partialpath
				<<local (ctdays = 0, maxdays = adrblog^.prefs.ctDaysToDisplay, lastday = -1, itemstext = "", lastitemdate)
				<<
				<<local (dateList = {}, textList = {})
				<<local (bodytext)
				<<bundle //set bodytext
					<<on addDay ()
						<<if adrblog^.prefs.manila.enabled //01/25/01 JES: build homepage text for sending to a Manila site
							<<dateList = dateList + lastitemdate
							<<if system.environment.isMac //02/22/2001 JES: convert to Latin text
								<<textList = textList + latinToMac.macToLatin (itemstext)
							<<else
								<<textList = textList + itemstext
						<<local (s = string (adrblog^.prefs.daytemplate))
						<<s = string.replaceall (s, "<%longDate%>", date.longstring (lastitemdate), false)
						<<s = string.replaceall (s, "<%shortDate%>", date.shortstring (lastitemdate), false)
						<<s = string.replaceall (s, "<%dayOfWeek%>", date.dayOfWeekToString (date.dayOfWeek (lastitemdate)), false)
						<<s = string.replaceall (s, "<%items%>", itemstext, false); itemstext = ""
						<<bundle //PBS 02/22/01: archive link
							<<local (day, month, year, hour, minute, second)
							<<date.get (lastitemdate, @day, @month, @year, @hour, @minute, @second)
							<<local (dateString = string.mid (year, 3, 2) + "/" + string.padWithZeros (month, 2) + "/" + string.padWithZeros (day, 2))
							<<local (imgTag = "<img src=\"http://scripting.com/images/dailyLinkIcon.gif\" height=\"19\" width=\"13\" alt=\"Permanent link to archive for " + dateString + ".\" border=\"0\">")
							<<local (archiveUrl = "")
							<<if not flArchivePage
								<<archiveUrl = year + "/" + string.padWithZeros (month, 2) + "/" + string.padWithZeros (day, 2) + ".html"
							<<if catName != nil //PBS 03/18/01: the archive URL for category pages needs to pop up a level
								<<archiveUrl = "../" + archiveUrl
							<<local (archiveLink = html.getLink (imgTag, archiveUrl))
							<<s = string.replaceAll (s, "<%archiveLink%>", archiveLink, false)
						<<bodytext = bodytext + s + "\r\n"
					<<bodytext = "\r\n"
					<<local (i, adrpost, s, enclosurelink)
					<<for i = sizeof (adrblog^.posts) downto 1
						<<adrpost = @adrblog^.posts [i]
						<<bundle //PBS 02/22/01: check min and max dates
							<<if adrpost^.when < minDate
								<<break
							<<if adrpost^.when > maxDate
								<<continue
						<<bundle //only include if in category, if catname was specified
							<<if catname != nil
								<<local (flskip = true)
								<<if defined (adrpost^.categories)
									<<local (adrthiscat = @adrpost^.categories.[catname])
									<<if defined (adrthiscat^)
										<<if adrthiscat^
											<<flskip = false
								<<if flskip
									<<continue
						<<bundle //check date rollover
							<<local (when = adrpost^.when, day, month, year, hour, minute, second)
							<<date.get (when, @day, @month, @year, @hour, @minute, @second)
							<<if lastday == -1 //first time through loop
								<<lastday = day
							<<else
								<<if day != lastday
									<<ctdays++
									<<if ctdays == maxdays
										<<break
									<<lastday = day
									<<addDay ()
						<<bundle //set enclosurelink
							<<if defined (adrpost^.enclosure)
								<<enclosurelink = "<a href=\"" + adrpost^.enclosure.url + "\">" + radio.data.strings.enclosureImg + "</a>"
							<<else
								<<enclosurelink = ""
						<<local (sourcelink = "")
						<<bundle //set sourcelink
							<<if defined (adrpost^.sourceUrl)
								<<local (adrdata = xml.aggregator.init ())
								<<local (adrsource = @adrdata^.services.[adrpost^.sourceUrl])
								<<if defined (adrsource^)
									<<sourcelink = "<a href=\"" + adrsource^.compilation.channellink + "\" title=\"Source: " + adrsource^.compilation.channeltitle + ".\">" + adrblog^.prefs.sourceImgTag + "</a>"
						<<s = string (adrblog^.prefs.itemtemplate)
						<<s = string.replaceall (s, "<%text%>", string (adrpost^.text), false)
						<<s = string.replaceall (s, "<%enclosure%>", enclosurelink, false)
						<<s = string.replaceall (s, "<%source%>", sourcelink, false)
						<<s = string.replaceall (s, "<%when%>", date.timestring (adrpost^.when), false)
						<<itemstext = itemstext + s + "\r\n"
						<<lastitemdate = adrpost^.when
					<<if itemstext != "" //there was some text left over when loop finished
						<<addDay ()
				<<
				<<local (s = string (adrblog^.prefs.template), description = string (adrblog^.prefs.description))
				<<bundle //set description if it's a category
					<<if catname != nil
						<<description = adrcat^.description
				<<bundle //do macro substitutions
					<<s = string.replaceall (s, "<%bodytext%>", bodytext, false)
					<<s = string.replaceall (s, "<%title%>", adrblog^.prefs.title, false)
					<<s = string.replaceall (s, "<%description%>", description, false)
					<<s = string.replaceall (s, "<%authorname%>", adrblog^.prefs.authorname, false)
					<<s = string.replaceall (s, "<%authormailaddress%>", adrblog^.prefs.authormailaddress, false)
					<<s = string.replaceall (s, "<%year%>", date.year (), false)
					<<s = string.replaceall (s, "<%now%>", clock.now (), false)
					<<bundle //PBS 02/21/01: RSS link
						<<local (imgTag = "<img src=\"http://scripting.com/images/xml.gif\" height=\"14\" width=\"36\" alt=\"Click here to see the XML version of this weblog.\" border=\"0\">")
						<<local (rssLink = html.getLink (imgTag, radio.weblog.getRssUrl (adrblog)))
						<<s = string.replaceAll (s, "<%rssLink%>", rssLink, false)
					<<bundle //PBS 02/23/01: Radio badge
						<<local (imgTag)
						<<if defined (user.html.glossary.radioBadge)
							<<imgTag = user.html.glossary.radioBadge
						<<else //hard-code, just in case a beta user doesn't have the glossary entry
							<<imgTag = "<img src=\"http://scripting.com/images/radioUserlandBadge2.gif\" width=\"88\" height=\"31\" border=\"0\" alt=\"This site is edited with Radio UserLand, the first personal Web Application server for Windows and Macintosh.\">"
						<<local (link = html.getLink (imgTag, "http://radiodiscuss.userland.com/"))
						<<s = string.replaceAll (s, "<%radioBadge%>", link)
				<<
				<<if system.environment.isMac //02/22/2001 JES: iso8859 encode the HTML rendering
					<<s = string.iso8859encode (s, @html.data.iso8859.mac)
				<<else
					<<s = string.iso8859encode (s, @html.data.iso8859.win)
				<<file.surefilepath (f)
				<<file.writewholefile (f, s, 'TEXT', user.html.prefs.textFileCreator) //02/22/2001 JES: added type/creator
				<<
				<<if adrblog^.prefs.flPublicBlog
					<<if not flArchivePage
						<<thread.callScript (@radio.weblog.notify, {adrblog})
				<<bundle //do FTP and Manila mirroring
					<<if adrblog^.prefs.ftp.enabled
						<<local (fname = filepath)
						<<fname = string.nthfield (fname, "/", string.countfields (fname, "/"))
						<<if flArchivePage
							<<fname = archiveFtpPath
						<<if catname != nil
							<<fname = "categories/" + fname
							<<adrcat^.htmlUrl = adrblog^.prefs.ftp.url  + "categories/" + adrcat^.filename + ".html"
						<<radio.weblog.uploadFile (adrblog, fname, s, adrconnection)
					<<if adrblog^.prefs.manila.enabled //01/25/01 JES: send new homepage(s) text to Manila site
						<<if not flArchivePage
						<<if sizeOf (dateList) != 0
							<<if catname == nil
								<<radio.weblog.uploadManila (adrblog, dateList, textList)
				<<if user.radio.prefs.flLogWeblogPublish
					<<local (url = filepath)
					<<if not (url beginswith "/")
						<<url = "/" + url
					<<local (htmltext = "<a href=\"" + url + "\">" + adrblog^.prefs.title + "</a>.")
					<<radio.log.add ("Weblog publish", htmltext, startticks)
		<<Archive
			<<8/15/01; 6:50:56 PM by JES
				<<Changed macro delimiters from { and } to <% and %>.
			<<3/18/01; 4:07:28 PM by PBS
				<<Fixed the incorrect archive link URL on category pages.
			<<3/18/01; 2:50:03 PM by PBS
				<<The default minimum and maximum date strings didn't work on some international systems -- there was an error coercing to date. So use date.set instead.
			<<3/2/01; 12:35:00 PM by JES
				<<Use the same file extension for writing archive files as was specified for the home page.
			<<3/1/01; 11:22:56 PM by JES
				<<Respect user.html.prefs.textFileCreator when writing out the file.
			<<2/27/01; 4:44:07 PM by PBS
				<<Get the Radio badge from the global glossary.
			<<2/24/01; 1:57:57 AM by JES
				<<Fixed terminology mismatch; changed Blog Publish to Weblog Publish.
			<<2/23/01; 6:12:56 PM by PBS
				<<New macro: {radioBadge} adds a Radio badge.
			<<2/23/01; 3:27:05 PM by PBS
				<<Use xml.gif and dailyLinkIcon.gif on UserLand servers -- don't attempt to upload or upstream.
			<<2/22/01; 9:32:15 PM by JES
				<<Convert accented characters in the HTML rendering to entities. If this is a Mac, convert text to Latin for Manila mirroring.
			<<2/22/01; 5:06:08 PM by JES
				<<adrconnection is a new optional parameter, the connection table for an FTP session already opened. This is passed to radio.weblog.uploadFile.
			<<2/22/01; 11:49:14 AM by PBS
				<<d is an optional parameter, a date in an archive day that you want to publish.
				<<archiveLink macro points to the archive page for a day.
			<<2/21/01; 4:26:46 PM by PBS
				<<New macro: rssLink gets you an XML button that links to the RSS version of your weblog.
			<<1/25/01; 11:46:14 PM by JES
				<<Implement mirrroring on Manila sites.
			<<1/25/01; 2:49:06 PM by DW
				<<Set the htmlUrl for categories. Give precedence to the FTP url over the upstreaming url.
			<<1/25/01; 10:53:08 AM by DW
				<<Added alt attributes for images, working towards validation.
				<<Reorganize code.
				<<Do notification in a thread. (So it can wait for an ignored response while we're FTPing.)
				<<Add optional param that allows the rendering to be saved in a different file but in the same folder as the home page. 
			<<1/24/01; 5:54:25 PM by DW
				<<If an item has a source, link to it through the {enclosure} macro. If it has no source, the icon isn't displayed.
			<<1/19/01; 3:24:14 PM by DW
				<<If an item has an enclosure, link to it through the {enclosure} macro. If it has no enclosure, the icon isn't displayed.
	
	local (startticks = clock.ticks ());
	local (f, adrcat);
	local (flIndexPage = (typeOf (d) == unknownType) );
	
	if catname != nil { //set adrcat
		adrcat = @adrblog^.categories.[catname];
		if not defined (adrcat^.flRenderHtml) { //initialize to false
			adrcat^.flRenderHtml = false};
		if not adrcat^.flRenderHtml { //do nothing
			return ("")}};
	bundle { //set f
		on getArchiveFilePath (relfolder, d) { //get the path to an archive file for a given date
			local (day, month, year, hour, minute, second);
			date.get (d, @day, @month, @year, @hour, @minute, @second);
			month = string.padWithZeros (month, 2);
			day = string.padWithZeros (day, 2);
			return (relfolder + year + "/" + month + "/" + day + ".txt")};
		if flIndexPage {
			if catname == nil { //weblog home page
				f = radio.file.getAbsolutePath (adrblog^.prefs.homePageFilePath);
				bundle { //add it to system.temp.radio.pingAfterUpstream
					if true { //adrblog^.prefs.flPublicBlog
						local (adrtable = @system.temp.radio.pingAfterUpstream.[f]);
						new (tabletype, adrtable);
						adrtable^.flUpstreamed = false;
						adrtable^.name = adrblog^.prefs.title;
						adrtable^.url = radio.weblog.getUrl (adrblog)}}}
			else { //category home page
				f = radio.file.getAbsolutePath (adrblog^.prefs.htmlCategoryFolderPath + adrcat^.fileName + "/" + "index.txt");
				bundle { //add it to system.temp.radio.pingAfterUpstream
					if adrcat^.flNotifyWeblogsCom {
						local (adrtable = @system.temp.radio.pingAfterUpstream.[f]);
						new (tabletype, adrtable);
						adrtable^.flUpstreamed = false;
						adrtable^.name = adrcat^.displayName;
						adrtable^.url = adrcat^.htmlUrl}}}}
		else { //archive page
			if catname == nil { //weblog archive page
				local (homeRelPath = adrblog^.prefs.homePageFilePath);
				local (homeFileName = string.nthField (homeRelPath, "/", string.countFields (homeRelPath, "/")));
				local (relFolder = string.mid (homeRelPath, 1, sizeOf (homeRelPath) - sizeOf (homeFileName)));
				f = radio.file.getAbsolutePath (getArchiveFilePath (relFolder, d))}
			else { //category archive page
				local (relFolder = adrblog^.prefs.htmlCategoryFolderPath + adrcat^.fileName + "/");
				f = radio.file.getAbsolutePath (getArchiveFilePath (relfolder, d))}}};
	
	if file.exists (f) { //touch the file
		<<file.setModified (f, clock.now ())
		local (adrfile);
		if radio.file.getFileAttributes (f, @adrfile) {
			adrfile^.upstream.whenLastUploaded = date (0)}}
	else { //build the text of the file, and write it to disk
		local (filetext);
		bundle { //build filetext
			local (eol);
			bundle { //set line ending characters: eol
				if system.environment.isMac {
					if system.environment.isCarbon {
						eol = "\n"}
					else { //classic
						eol = "\r"}}
				else { //windows
					eol = "\r\n"}};
			on add (s) {
				filetext = filetext + s + eol};
			
			local (startMacro, endMacro);
			bundle { //set startMacro, endMacro -- the macro delimiter strings
				local (adrsite = @radio.data.website);
				local (adrsiteprefs = @adrsite^.["#prefs"]);
				startMacro = adrsiteprefs^.macroStartCharacters;
				endMacro = adrsiteprefs^.macroEndCharacters};
			on addMacro (s) {
				add (startMacro + s + endMacro)};
			
			add ("#flHomePage true"); //all weblog pages use the #homePageTemplate
			if flIndexPage { //#flArchivePage is false
				add ("#flArchivePage false")}
			else { //#flArchivePage is true
				add ("#flArchivePage true")};
			if flIndexPage and catname == nil { //#flSystemPage is true
				add ("#flSystemPage true")};
			<<if catname != nil //add #categoryName directive
				<<add ("#categoryName \"" + catname + "\"")
			if not flIndexPage { //add #archiveDate directive
				local (day, month, year, hour, minute, second);
				date.get (d, @day, @month, @year, @hour, @minute, @second);
				month = string.padWithZeros (month, 2);
				day = string.padWithZeros (day, 2);
				local (datestring = year + "/" + month + "/" + day);
				add ("#archiveDate \"" + datestring + "\"")};
			addMacro ("radio.macros.viewWeblog ()")};
		
		file.sureFilePath (f);
		file.writeTextFile (f, filetext)};
	
	if not flIndexPage {
		if adrblog^.prefs.flArchiveMonthly {
			bundle { //set f
				on getArchiveFilePath (relfolder, d) { //get the path to the monthly archive file for a given date
					local (day, month, year, hour, minute, second);
					date.get (d, @day, @month, @year, @hour, @minute, @second);
					month = string.padWithZeros (month, 2);
					return (relfolder + year + "/" + month + "/" + "index.txt")};
				if catname == nil { //weblog monthly archive page
					local (homeRelPath = adrblog^.prefs.homePageFilePath);
					local (homeFileName = string.nthField (homeRelPath, "/", string.countFields (homeRelPath, "/")));
					local (relFolder = string.mid (homeRelPath, 1, sizeOf (homeRelPath) - sizeOf (homeFileName)));
					f = radio.file.getAbsolutePath (getArchiveFilePath (relFolder, d))}
				else { //category monthly archive page
					local (relFolder = adrblog^.prefs.htmlCategoryFolderPath + adrcat^.fileName + "/");
					f = radio.file.getAbsolutePath (getArchiveFilePath (relfolder, d))}};
			if file.exists (f) { //touch the file
				local (adrfile);
				if radio.file.getFileAttributes (f, @adrfile) {
					adrfile^.upstream.whenLastUploaded = date (0)}}
			else { //build the text of the file, and write it to disk
				local (filetext);
				bundle { //build filetext
					local (eol);
					bundle { //set line ending characters: eol
						if system.environment.isMac {
							if system.environment.isCarbon {
								eol = "\n"}
							else { //classic
								eol = "\r"}}
						else { //windows
							eol = "\r\n"}};
					on add (s) {
						filetext = filetext + s + eol};
					
					local (startMacro, endMacro);
					bundle { //set startMacro, endMacro -- the macro delimiter strings
						local (adrsite = @radio.data.website);
						local (adrsiteprefs = @adrsite^.["#prefs"]);
						startMacro = adrsiteprefs^.macroStartCharacters;
						endMacro = adrsiteprefs^.macroEndCharacters};
					on addMacro (s) {
						add (startMacro + s + endMacro)};
					
					add ("#flArchivePage false");
					add ("#flMonthlyArchive true");
					local (day, month, year, hour, minute, second);
					date.get (d, @day, @month, @year, @hour, @minute, @second);
					month = string.padWithZeros (month, 2);
					local (datestring = year + "/" + month + "/01");
					add ("#archiveDate \"" + datestring + "\"");
					addMacro ("radio.macros.viewWeblog ()")};
				
				file.sureFilePath (f);
				file.writeTextFile (f, filetext)}};
		if adrblog^.prefs.flArchiveWeekly {
			local (startWeekDate);
			bundle { //set f
				on getFirstDayOfWeek (archiveDate) { //get the first day of the week (Sunday)
					local (counter, dayOfWeek);
					dayOfWeek = date.dayOfWeek (archiveDate);
					for counter = dayOfWeek downto 2 {
						archiveDate = date.yesterday (archiveDate)};
					return (archiveDate)};
				on getArchiveFilePath (relfolder, d) { //get the path to the weekly archive file for a given date
					startWeekDate = getFirstDayOfWeek (d);
					local (day, month, year, hour, minute, second, week);
					date.get (startWeekDate, @day, @month, @year, @hour, @minute, @second);
					week = date.weekInYear (startWeekDate);
					week = string.padWithZeros (week, 2);
					return (relfolder + year + "/week" + week + ".txt")};
				if catname == nil { //weblog weekly archive page
					local (homeRelPath = adrblog^.prefs.homePageFilePath);
					local (homeFileName = string.nthField (homeRelPath, "/", string.countFields (homeRelPath, "/")));
					local (relFolder = string.mid (homeRelPath, 1, sizeOf (homeRelPath) - sizeOf (homeFileName)));
					f = radio.file.getAbsolutePath (getArchiveFilePath (relFolder, d))}
				else { //category weekly archive page
					local (relFolder = adrblog^.prefs.htmlCategoryFolderPath + adrcat^.fileName + "/");
					f = radio.file.getAbsolutePath (getArchiveFilePath (relfolder, d))}};
			if file.exists (f) { //touch the file
				local (adrfile);
				if radio.file.getFileAttributes (f, @adrfile) {
					adrfile^.upstream.whenLastUploaded = date (0)}}
			else { //build the text of the file, and write it to disk
				local (filetext);
				bundle { //build filetext
					local (eol);
					bundle { //set line ending characters: eol
						if system.environment.isMac {
							if system.environment.isCarbon {
								eol = "\n"}
							else { //classic
								eol = "\r"}}
						else { //windows
							eol = "\r\n"}};
					on add (s) {
						filetext = filetext + s + eol};
					
					local (startMacro, endMacro);
					bundle { //set startMacro, endMacro -- the macro delimiter strings
						local (adrsite = @radio.data.website);
						local (adrsiteprefs = @adrsite^.["#prefs"]);
						startMacro = adrsiteprefs^.macroStartCharacters;
						endMacro = adrsiteprefs^.macroEndCharacters};
					on addMacro (s) {
						add (startMacro + s + endMacro)};
					
					add ("#flArchivePage false");
					add ("#flWeeklyArchive true");
					local (day, month, year, hour, minute, second);
					date.get (startWeekDate, @day, @month, @year, @hour, @minute, @second);
					month = string.padWithZeros (month, 2);
					day = string.padWithZeros (day, 2);
					local (datestring = year + "/" + month + "/" + day);
					add ("#archiveDate \"" + datestring + "\"");
					addMacro ("radio.macros.viewWeblog ()")};
				
				file.sureFilePath (f);
				file.writeTextFile (f, filetext)}}};
	
	if user.radio.prefs.flLogWeblogPublish { //add to the events log
		local (url, linktext);
		if adrcat == nil {
			url = radio.weblog.getUrl ();
			linktext = adrblog^.prefs.title}
		else {
			if defined (adrcat^.rssUrl) {
				url = adrcat^.rssUrl}
			else {
				url = ""};
			linktext = nameOf (adrcat^);
			if defined (adrcat^.displayName) {
				linktext = adrcat^.displayName}};
		if not flIndexPage {
			linktext = linktext + "; " + date.shortString (d)};
		local (htmltext = "<a href=\"" + url + "\">" + linktext + "</a>.");
		radio.log.add ("Weblog publish", htmltext, startticks)};
	bundle { //bump hourlyUpdate counter -- 6/5/02 by DW
		local (day, month, year, hour, minute, second);
		date.get (clock.now (), @day, @month, @year, @hour, @minute, @second);
		adrblog^.stats.hourlyUpdateCounts.[string.padwithzeros (hour, 2)]++};
	
	return (f)};

<<bundle //test code
	<<bundle //publish one category
		<<publish (catname:"michegas")
	<<bundle //publish home page
		<<publish ()
	<<bundle //publish today
		<<publish (d:clock.now ())
	<<bundle //publish all categories
		<<local (adr)
		<<for adr in @weblogData.categories
			<<msg (nameof (adr^))
			<<publish (catname:nameof (adr^))
	<<bundle //publish today for all categories
		<<local (adr)
		<<for adr in @weblogData.categories
			<<msg (nameof (adr^))
			<<publish (catname:nameof (adr^), d:clock.now ())



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.