on writeMyRssFile (f, title, link, description, language="none", flCategories=false, maxdays=infinity, adrcallback=nil, adrblog=radio.weblog.init (), adrGetUrlCallback=nil, ttl=60) { bundle { //check with callbacks, allow wholesale override of writeRssFile functionality try { local (adrscript); for adrscript in @user.radio.callbacks.writeRssFile { try { while typeof (adrscript^) == addresstype { adrscript = adrscript^}; return (adrscript^ (f, title, link, description, language, flCategories, maxdays, adrcallback, adrblog, adrGetUrlCallback)); }}}}; local (adrcache); bundle { //set adrcache local (adrtable = @system.temp.radio.rssCache); if not defined (adrtable^) { new (tabletype, adrtable)}; adrcache = @adrtable^.[f]; if not defined (adrcache^) { new (tabletype, adrcache)}; if not defined (adrcache^.items) { new (tabletype, @adrcache^.items); }}; local (flCloud = false); bundle { //set flCloud try { if not file.exists (f) { //radio.file.getFileAttributes doesn't work if the file doesn't exist file.writeTextFile (f, " ")}; local (adrfile, adrspec); radio.file.getFileAttributes (f, @adrfile); radio.upstream.getUpstreamSpec (adrfile, @adrspec); if adrspec^.server == user.radio.prefs.rssCloud.server { if adrspec^.port == user.radio.prefs.rssCloud.port { if adrspec^.rpcPath == user.radio.prefs.rssCloud.path { flCloud = true; }}}}}; local (xmltext); bundle { //build 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))}}; add (""); add (""); add (""); indentlevel++; add (""); indentlevel++; add ("" + encode (title) + ""); add ("" + encode (link) + ""); add ("" + encode (description) + ""); if language != "none" { add ("" + language + "")}; bundle { //add the items local (i, adrpost, s, ctitems = 0); local (ctdays = 0, lastday = -1, itemstext = "", lastitemdate, flinclude); for i = sizeof (adrblog^.posts) downto 1 { adrpost = @adrblog^.posts [i]; 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}}}; bundle { //set flinclude flinclude = true; if adrcallback != nil { try {flinclude = adrcallback^ (adrpost)}}}; if flinclude { add (""); indentlevel++; bundle { //add title and link present in the post, if enabled if adrblog^.prefs.flTitleAndLinkOnPostForm { if defined (adrpost^.title) { if sizeOf (adrpost^.title) > 0 { add ("" + encode (adrpost^.title) + "")}}; if defined (adrpost^.link) { add ("" + encode (adrpost^.link) + "")} else { //if the auto-generate-links pref is set, use a generated link if possible if adrblog^.prefs.flAutoGenerateLinks { if adrGetUrlCallback != nil { local (url, flincludelink = false); try {flincludelink = adrGetUrlCallback^ (adrpost, @url)}; if flincludelink { add ("" + url + "")}}}}}}; bundle { //add description, either from the cache, or by recalcing local (flrecalc = true); local (adritemcache = @adrcache^.items.[nameof (adrpost^)]); if defined (adritemcache^) { if timeModified (@adrpost^.text) <= adritemcache^.when { flrecalc = false}}; if flrecalc { local (itemtext = string (adrpost^.text)); bundle { //call the description filter callbacks, 4/11/02 by DW try { local (adrscript); for adrscript in @adrblog^.callbacks.rssFilterDescription { try { while typeof (adrscript^) == addresstype { adrscript = adrscript^}; itemtext = adrscript^ (itemtext, adrpost)}}}}; bundle { //process macros in the description, into itemtext, 4/7/02 by DW local (pt); new (tabletype, @pt); pt.macroStartCharacters = "<%"; pt.macroEndCharacters = "%>"; pt.processMacrosInHtmlTags = true; pt.tools = @radio.data.website.["#tools"]; try {itemtext = encode (html.processmacros (itemtext, adrpagetable:@pt))}}; «itemtext = encode (radio.string.processMacros (string (adrpost^.text))) new (tabletype, adritemcache); adritemcache^.text = itemtext; adritemcache^.when = clock.now ()}; add ("" + adritemcache^.text + "")}; bundle { //add guid and pubDate from the RSS 2.0 spec bundle { //add guid if adrGetUrlCallback != nil { local (uri, ispermalink = false); try {ispermalink = adrGetUrlCallback^ (adrpost, @uri)} else { local (folder = file.folderFromPath (f)); local (urlfolder = radio.upstream.getFileUrl (folder)); local (day, month, year, hour, minute, second); date.get (adrpost^.when, @day, @month, @year, @hour, @minute, @second); uri = urlfolder + year + "/" + string.padwithzeros (month, 2) + "/" + string.padwithzeros (day, 2) + ".html#a" + number (nameOf (adrpost^)); add ("" + uri + "")}}}}; if defined (adrpost^.sourceName) and defined (adrpost^.sourceUrl) { add ("" + encode (adrpost^.sourceName) + "")}; if defined (adrpost^.enclosure) { with adrpost^.enclosure { if not defined (error) { add ("")}}}; if flCategories { if defined (adrpost^.categories) { local (adr); for adr in @adrpost^.categories { add ("" + encode (nameof (adr^)) + "")}}}; add (""); indentlevel--; lastitemdate = adrpost^.when; if ++ctitems >= adrblog^.prefs.maxOutputItemsPerChannel { break}}}}; add (""); indentlevel--; add (""); indentlevel--}; file.sureFilePath (f); file.writeTextFile (f, xmltext); return (xmltext)}