¶„NXi€ ¹-¹-€ º Ì@8ÖÈChicago?ÿ ÿÿÿÿÿÿÿÿ Lucida Grande AšèàGeneva ^=¸ÃChicago?ÿ m.©ÒChicago?ÿ ÿÿÿÿÿÿÿÿ Lucida Grande ÿÿº ¹-¹-< 40¹-¹- prefs"J4€§--V¹-¹-  %= IM Y] bz¹-† ŽauthorCharles Miller authorEmailcmiller@pastiche.org description€§@¶§--;&­– ¢ ~ÓX @ ¹-¹.+4 VÀGeneva ¹-¹-'?ïÀLANDÿÿÿÿÿÿmac on any (pta) //boilerplate for your responder pta^.responseHeaders.["Content-Type"] = "text/html" pta^.code = 200 //everything was OK pta^.responseBody = "" //build response return (true) €€€€€V2.¹-¹- anyá2™•.¹-¹- GÿÿÿO W condition9(string.lower (path) beginsWith "/aggregatorcategories/")enabledmethodsÈC™ ¹-¹- ¹-¹- €ÓXGeneva ¹-¹-'?ïÀLANDÿÿÿÿÿÿmac This script runs every hour. „›€X€¸e—8¹-¹-¬  ! 5A Olib"Nmenu" statusCenterMessage" • viewNewsItems"&­VGeneva Ùo=œŒ®?´HGeneva ¹- x¹- Ž'?ïÀLANDÿÿÿÿÿÿmac lib viewNewsItems displayHtml menu statusCenterMessage viewNewsItems €îx騀îxåð€îx笀îx騀îx騀îx騀)žGeneva ¹-¹.+u'?ïÀLANDÿÿÿÿÿÿmac dialog.notify ("Improved") €€Ó°Geneva ¹-¹.+‚Ô'?ïÀLANDÿÿÿÿÿÿmac AggregatorCategories About... €€ i”÷Ú°p ]6$àÜGeneva  t Œp }Geneva ¹-¹-'?ïÀLANDÿÿÿÿÿÿmac This script returns a string which appears in the Status Center on the Radio UserLand home page. return ("I'm a cool Tool!") „€€ ~.¹-¹-×  %1 ?menu" statusCenterMessage" • vi€j( ¢jVì~¸X €žGeneva ¹-¹-'?ïÀLANDÿÿÿÿÿÿmac This script runs in its own thread. loop //loop until the application quits Add your code here. thread.sleepFor (10) //sleep for ten seconds „€„€€ÉTP.¹-¹-ÿÿÿ ctenabledscriptÈ L€)€Ä†tArial ¶Fû¶Fû 2®LANDÿÿÿÿÿÿmac on finalFilter (pta) pta^.renderedText = string.replace (pta^.renderedText, "[[title]]", "") return (true) €�����€�����€��������þ€�º������†� ���-����Geneva���������������������������� ��������������­ÂEu´`ÞQ������ �2LANDÿÿÿÿÿÿ������mac ������������on firstFilter (adrPageTable) return (true) €�����€��������±€�ý������†�*��[����Geneva���������������������������� ��������������­ÂEuµü7a���m���L�3*lLANDÿÿÿÿÿÿ������mac ������������on pageFilter (pta) if typeOf (pta^.template) == outlineType or typeOf (pta^.template) == wpTextType table.assign (@pta^.template, string (pta^.template)) if typeOf (pta^.template) == stringType and not pta^.indirectTemplate pta^.template = string.replace (pta^.template, "<title>", "[[title]]") html.addPageToGlossary (pta) return (true) €�����€�����€�����€�����€�����€�����€�����€�ù€� ������--���.���­ÂE¼¶Fû�������� ���� ��� ����$���0 ����; finalFilter�������× firstFilter�������á pagefilter�������ž��VGeneva���������������������������� ����������è�P�E��$Ï�������������������������Ó€� ,������--������µü7¨¹-�������� ����url���&http://127.0.0.1/aggregatorCategories/���P€��n������--����������µü8H������VArial����������������������������� ���������������������������������������������€��Ê€�V������†����������´ž–������������space���/GIFfGIF89a��€��ÿÿÿ���!ù����,�������D�;��VArial����������������������������� ������������������������������������������������±€�™������†���V�������´ž†�������� ������� �������"�������+ ����0���: ����C���L ����Q���[ ����aalink���008000bgcolor���FFFFFFflRenderlink���0000FFspaceGif���spacetext���000000vlink���800080��VArial����������������������������� �����������������������������������������������€�n������†�<���°�����Arial����������������������������� ��������������¶Fû¶Fû������ �‹LANDÿÿÿÿÿÿ������mac ������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>{title} {metaTags ()} {bodyTag ()} {bodytext} €€€€€€€€€€€d€þDµü8>VArial n€„D000000060001001777AA00000000005A000000001001710190490021800000‚‚6000600329200-1‚0Â3‚2921FFFFF0‚‚10ÂE0000100000031000000010E840‚‚3‚2921FE048E000163293000020000001200000000E,#title "Home" 000400000009000000020100000500000009000000020100000600000032000000010ÁF310‚‚ÁFFFF0‚C00000 20ÂÁ ‚‚Á‚000700000019000000010‚20Â1E0‚Á‚0008000000A90000000140,Geneva40,10A0304E44000‚‚10Â10000900000015000000020‚961770‚96177000A00000015000000023‚2921F3‚2921F000B00000005000000020Â000C0000001200000001E36‚9AF10‚000F0000005200000000400 10 ‚ÂÁÂÁ‚‚ÁÂ4,appn4,send4,8óð4,&4,8ô€4,3©4,8ôð00130000007E00000000DA91F8CE1C1D1E1F7F1B044,-.¶µ•µ¥¥.'"‘’“”…ƒFFFF0FFFF0FFFE000000060001001777AA±§Pĵü7¨}5#¼€``µü7¶Fû  * 4@ HT [g q} „ –#filtersȧ#ftpSiteȆ #glossaryÈâ#imagesÈ\#prefsÈ #templateÈD#toolsÈ´indexÈ.VVerdana º“??8“ò€|€~¹-¹- €ì~t¹-¹- % >J ht ’€AŸ Geneva ¹- —¹- êKÐnLANDÿÿÿÿÿÿmac on generateHtml(stories) €€€ <8¹-¨¹-Í  viewNewsItemsà /<€ ¢¹-͹- — displayHtml 2VGeneva€Q0–Q ¢žVì~¸X €‘7¹-͹- ã generateHtmljVVGeneva ©‡2@8ÖÈ‘Õ-wV¹-¹.+^ % >J ht ’ž ¾Ê ë÷ aggregatorCategoriesData5vaggregatorCategoriesInfo5h@aggregatorCategoriesNodeTypes5µaggregatorCategoriesResponder5aggregatorCategoriesRpcHandlers5& aggregatorCategoriesSoapHandlers5RaggregatorCategoriesSuite5*»VGeneva ©22x;\vCGeneva ¹-¹.,IÕ'?ïÀLANDÿÿÿÿÿÿmac aggregatorCategoriesData aggregatorCategoriesInfo author authorEmail description homePageUrl name releaseDate version aggregatorCategoriesNodeTypes aggregatorCategoriesResponder aggregatorCategoriesRpcHandlers aggregatorCategoriesSoapHandlers aggregatorCategoriesSuite lib menu statusCenterMessage viewNewsItems €îxŒû¨€îxŒû¨€îxÙ€îxÙ€îxÙ€îxÙ€îxÙ€îxÙ€îxÙ€îxŒû¨€îxŒû¨€îxŒû¨€îxŒû¨€îxŒû¨€îx騀îx騀îx騀îx騨€îxŒû¨Õ€–>FzGeneva ¹-й-ÞERÇ—LANDÿÿÿÿÿÿmac on viewNewsItems (ctStoriesToList = user.radio.prefs.ctStoriesOnNewsPage) Changes: 5/13/02; 1:09:13 PM by JES Don't decode HTML entities when adding story text to the page. Entities have already been decoded when the aggregator did its scan. 1/28/02; 6:27:56 PM by JES Convert line endings in news items to CR line endings, so auto-paragraph expansion will work as expected. 1/25/02; 10:37:48 AM by DW Another optimization for the News Aggregator page. In the local "add" procedure, we parenthesize the text we're adding to htmltext, this triggers an ancient optimization in the kernel that doesn't do any handle copying on string assignments of the form x = x + s. Before parenthesizing average time was 104 ticks, after -- 45! More than double the speed. Worth doing. 1/24/02; 6:19:18 PM by DW Tweak for performance€¾8&­¾– ¢žVì~)X €f—8¹-¹-¬  ! 5A OlibNmenu statusCenterMessage • viewNewsItems bVGeneva Ùo=œŒ®?´IGeneva ¹- x¹- ã'?ïÀLANDÿÿÿÿÿÿmac lib viewNewsItems generateHtml menu statusCenterMessage viewNewsItems €îx騀îxåð€îx笀îx騀îx騀îxé¨f€;&­DFéGeneva ¹-й-4r†\¡LANDÿÿÿÿÿÿmac on viewNewsItems (ctStoriesToList = user.radio.prefs.ctStoriesOnNewsPage) Changes: 5/13/02; 1:09:13 PM by JES Don't decode HTML entities when adding story text to the page. Entities have already been decoded when the aggregator did its scan. 1/28/02; 6:27:56 PM by JES Convert line endings in news items to CR line endings, so auto-paragraph expansion will work as expected. 1/25/02; 10:37:48 AM by DW Another optimization for the News Aggregator page. In the local "add" procedure, we parenthesize the text we're adding to htmltext, this triggers an ancient optimization in the kernel that doesn't do any handle copying on string assignments of the form x = x + s. Before parenthesizing average time was 104 ticks, after -- 45! More than double the speed. Worth doing. 1/24/02; 6:19:18 PM by DW Tweak for performance. Uncached news page went from approx 220 ticks to approx 40 ticks. Thanks to Duncan Smeed for the trick to get add () to be so much faster. We'll surely use this in other places. 1/9/02; 12:34:03 AM by JES Fixed a bug where the class="dwsTableCellHeader" was mistakenly added to the 's for the headers, instead of being added to the 's. 1/6/02; 4:00:15 AM by JES Added table css classes. 12/19/01; 11:04:58 AM by JES If user.radio.prefs.flNewsPageReturnAfterPost is true, add the referer to the searchArgs on the link for the Post button. This causes the weblog post form to redirect back to the News page after posting an item. 12/18/01; 3:43:14 PM by JES Don't add the referer to the searchArgs on the link for the Post button. This prevents you from being redirected back to the News page after posting an item. 12/8/01; 11:56:49 AM by DW Intro text says "uncheck those you want to keep" if the preference is set to have checkboxes turned on by default. 12/1/01; 3:00:09 PM by JES Fixed a macro error when the user has hit the Back button after deleting a story, and tries to delete the story again. Added a Delete button to the bottom of the page. Decode entities and untaint channel titles and news items' text. 11/24/01; 3:31:11 PM by DW Linked into help system. 11/23/01; 4:41:15 PM by JES Changed user.radio.prefs.newsPageDeleteCheckboxesDefault to user.radio.prefs.flNewsPageDeleteCheckboxesDefault. 11/21/01; 3:31:33 PM by JES Fixed macro error: "[Macro error: Can't find a sub-table named "system.verbs.builtins.radio.html.viewNewsItems".]", when deleting items while a scan is in progress. if defined (adrcache^) ...references to adrincache^ are ok 11/3/01; 10:51:00 PM by JES Fixed the url on the redirect searchArg, so that the page will load to the last-posted news item. 10/22/01; 1:55:35 PM by JES Fixed a bug where news items could not be deleted because an address was improperly dereferenced. 10/20/01; 12:38:03 AM by JES Added the menu searcharg to the mag-glass links, and to the redirect url for the Unsubscribe button, which appears on single-channel pages. 8/14/01; 11:50:02 PM by JES If storyText is not defined for a given story, skip it. This averts "storyText hasn't been defined" errors. 8/14/01; 1:58:42 AM by JES Add the post number to the path-part of the referer searchArg, so the page will reload to the same news item after posting. Archive: 1/8/01; 8:53:17 AM by DW Added support for the viewStories cache. 1/8/01; 10:55:56 AM by DW Factored calls to myUserLandSuite.images.imageRef. 1/11/01; 4:40:45 PM by PBS If displaying a category page, add the attributes at the top. The title and description of the category can be edited. This is actually handled in another script: radio.html.editCategory Commented out some debugging code (a scratchpad reference) that had been left in place. If displaying a category page, use the displayName for the category. Make sure the title of the page changes when the category name has changed. 1/12/01; 1:48:52 PM by PBS When editing a category, title and description appear at the end. 1/13/01; 6:08:33 PM by DW Only show items with enclosures after the enclosure has been downloaded. 1/19/01; 5:03:23 PM by DW Undo the last change, items with enclosures are visible. Items with enclosures have a media icon, if it's been downloaded, the icon points into the local file system, otherwise it points onto the Web. 1/21/01; 3:47:55 PM by DW Link the EDIT button to myBlog.wsf, instead of addRemove.wsf. 1/24/01; 4:29:55 PM by DW Show a checkmark if the item has an adrBlogPost in its table. 1/27/01; 5:01:03 PM by DW Change the EDIT button to POST. 2/12/01; 4:21:06 PM by PBS Link title for the magnifying glass: "View all stories in the [channel title] channel." 2/12/01; 4:34:35 PM by PBS Fixed bug where quotes and carets in a channel description would mess up rendering -- an example was Dave Winer: Two-Way Web, which has a description of You're soaking in it! ";->" 2/12/01; 5:25:25 PM by PBS Terminology fix -- when viewing one channel, refer to it as a channel, not as a service. Also, use different text at the top of the page when viewing one channel, since the page is *not* showing you the recent stories from all the channels you're subscribed to. Skip empty stories. 2/15/01; 2:49:58 PM by PBS Cleaned up. Mostly removed single-category stuff that was no longer used. Stories that are just images get displayed again. 2/23/01; 10:55:23 AM by PBS Terminology: weblog, not blog. 2/23/01; 4:04:47 PM by PBS Slight change to punctuation in the description at the top of the page. 2/23/01; 10:53:19 PM by JES Linked the Post button to weblog.wsf, instead of myBlog.wsf. 2/24/01; 9:40:04 PM by PBS Help link. 2/24/01; 11:35:08 PM by JES Bug fix: the default cache was not deleted when deleting stories while viewing a single channel. 2/24/01; 11:52:11 PM by JES Fixed cache deletion logic: When deleting an item via either the home page or a service page, delete both the default cache, and the service's cache. 2/25/01; 1:31:32 PM by PBS Set up a second cache for when it's not the same machine. 2/25/01; 2:26:50 PM by JES Separate cache for viewing single channels when it's not the same machine. 3/4/01; 6:11:10 PM by JES Reality check: Don't add the magnifying glass if the service's table is not defined. 3/5/01; 2:14:08 AM by JES Fixed bug where "default" is undefined when deleting a story while accessing the home page remotely. local (pta = html.getpagetableaddress ()) scratchpad.params = pta^ pta^.title = radio.string.getlocalizedstring ("aggregator.title") local (uri = pta^.uri) local (adrdata = xml.aggregator.init ()) local (htmltext = "", indentlevel = 0) on add (s) htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n"); on decodeEntities (s) s = string.replaceAll (s, "\r\n", "\r") s = string.replaceAll (s, "\n", "\r") return (radio.string.decodeEntities (s, flNeuterJavaScript:false)) local (flOneService = false, xmlUrl = "", adrservice) bundle //parse args if defined (pta^.radioResponder.getArgs) local (adrargs = @pta^.radioResponder.getArgs) if defined (adrargs^.xmlUrl) flOneService = true xmlurl = adrargs^.xmlUrl adrservice = @adrdata^.services.[xmlurl] if defined (adrservice^.compilation.channeltitle) //avoid errors for non-compliant channels add ("Channel: " + decodeEntities (adrservice^.compilation.channeltitle) + "

") pta^.title = "Channel: " + decodeEntities (adrservice^.compilation.channeltitle) local (adrcache = @adrdata^.cache.[this], adrincache, defaultcachename = "default") if not defined (adrcache^) //make sure the cache table is defined new (tabletype, adrcache) bundle //set adrincache if user.radio.prefs.flCacheNewsItemsPage local (cachename = defaultcachename) if sizeof (xmlUrl) > 0 cachename = xmlUrl if not pta^.radioResponder.flSameMachine cachename = cachename + "Remote" adrincache = @adrcache^.[cachename] bundle //catch post if pta^.method == "POST" local (adrargs = @pta^.radioResponder.postArgs) scratchpad.args = args; edit (@scratchpad.args) if defined (adrargs^.formName) if string.lower (adrargs^.formName) == "editstories" delete (@adrargs^.formName) if defined (adrargs^.unsubscribe) local (args) new (tabletype, @args) args.xmlUrl = xmlUrl if defined (adrdata^.services.[xmlUrl]) if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu local (url = "unsubscribe?" + webserver.encodeargs (@args)) radio.webServer.redirect (url) return ("") local (adrdefaultcache = @adrcache^.[defaultcachename]) for adrarg in adrargs local (name = string.padwithzeros (number (nameof (adrarg^)), 8)) local (adrstory = @adrdata^.stories.[name]) if defined (adrstory^) adrdata^.trash.[name] = adrstory^ delete (adrstory) if user.radio.prefs.flCacheNewsItemsPage if defined (adrcache^) if defined (adrincache^) //posting invalidates the cache delete (adrincache) if adrdefaultcache == adrincache //02/24/2001 JES: delete the cache for the service if defined (adrstory^) local (adrservicecache = @adrcache^.["xmlUrl=" + string.urlEncode (adrstory^.url)]) if defined (adrservicecache^) delete (adrservicecache) else //02/24/2001 JES: we're on the service page -- delete the default cache if defined (adrdefaultcache^) delete (adrdefaultcache) bundle //see if we can serve from the cache if defined (adrcache^) if defined (adrincache^) return (adrincache^) aggregatorCategoriesSuite.lib.viewNewsItems.generateHtml(ctStoriesToList, pta, adrdata, flOneService, xmlUrl) local (globeimg, xmlimg, searchimg, checkmarkimg, mediaimg, postbuttonimg)//, editbuttonimg) bundle //precalc img refs local (flSameMachine = pta^.radioResponder.flSameMachine) globeimg = radio.images.systemImageRef ("qbullet/remote", flFileUrl:flSameMachine) xmlimg = radio.images.systemImageRef ("icons/xml", flFileUrl:flSameMachine) searchimg = radio.images.systemImageRef ("qbullet/search", flFileUrl:flSameMachine) checkmarkimg = radio.images.systemImageRef ("icons/checkmark", flFileUrl:flSameMachine) editbuttonimg = radio.images.systemImageRef ("icons/editbutton", flFileUrl:flSameMachine) postbuttonimg = radio.images.systemImageRef ("icons/post", flFileUrl:flSameMachine) postbuttonimg = radio.images.systemImageRef ("icons/post2", flFileUrl:flSameMachine) mediaimg = radio.images.systemImageRef ("qbullet/sound", flFileUrl:flSameMachine) add ("

"); indentlevel++ add ("") //PBS 01/11/01: name the form, so the script doesn't try to process some other script's form add ("
  
") bundle //message at the top of the page if flOneService local (t) new (tabletype, @t) t.channeltitle = decodeEntities (adrservice^.compilation.channeltitle) add (radio.string.getlocalizedstring ("aggregator.oneChannelMessage", @t)) else local (t) new (tabletype, @t) t.subscriptionurl = radio.data.systemurls.subscriptionsList add (radio.string.getlocalizedstring ("aggregator.standardMessage", @t)) add (radio.string.getlocalizedstring ("aggregator.clickThePostButton")) if user.radio.prefs.flNewsPageDeleteCheckboxesDefault add (radio.string.getlocalizedstring ("aggregator.checkBoxesOnIntro")) else add (radio.string.getlocalizedstring ("aggregator.checkBoxesOffIntro")) if flOneService add (radio.string.getlocalizedstring ("aggregator.howToUnsubscribe")) add (" " + radio.userinterface.helpLink ("The News Aggregator page")) add ("

") add ("
"); indentlevel++ add (""); indentlevel++ local (adrtable = @adrdata^.stories, sizetable = sizeof (adrtable^), i) local (lastchanneltitle = "", ctstories = 0) for i = sizetable downto 1 local (adritem = @adrdata^.stories [i]) bundle //skip missing or empty stories if not defined (adritem^.storyText) //skip this story -- this can happen if the scan is interrupted continue if (string.trimWhiteSpace (searchEngine.stripMarkup (adrItem^.storyText)) == "") and (not (string.lower (adrItem^.storyText) contains " ctStoriesToList break if adritem^.channeltitle != lastchanneltitle //display channel title local (globe = "") bundle //link the globe to the HTML rendering of the channel with adrservice^.compilation globe = "" + globeimg + "" //PBS 02/12/01: fix bug where quotes and carets in a channel description would mess up rendering -- an example was Dave Winer: Two-Way Web, which has a description of You're soaking in it! ";->" local (xmllink) bundle //link the XML icon to the source XML file for the channel xmllink = "
" + xmlimg + "
" local (magglass = "") bundle //load up the magnifying glass with some HTML if not flOneService local (url, args) new (tabletype, @args) args.xmlUrl = adritem^.url if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu url = "?" + webserver.encodeArgs (@args) magglass = " " + searchimg + "" add ("") add ("
 " + globe + " " + decodeEntities (adrItem^.channelTitle) + ", " + adritem^.time + "." + magglass + "" + xmllink + "€;HDV¹-¹.,K  %= I ² ·Ï¹.X†Û ãauthorCharles Miller authorEmailcmiller@pastiche.org description4Incremental Improvements to the Radio New Aggregator homePageUrl!http://radio.weblogs.com/0100190/nameaggregatorCategories releaseDateversion0.1H¶8Geneva ¹-¹.+|'?ïÀLANDÿÿÿÿÿÿmac dialog.notify ("Improved Aggregator by Charles Miller") €¶6¢!ÖCGeneva 40¹- —¹.)B¶0 µLANDÿÿÿÿÿÿmac on generateHtml(ctStoriesToList, pta, adrdata, flOneService, xmlUrl) local (uri = pta^.uri) local (htmltext = "", indentlevel = 0) local (servicesTable = @adrdata^.services) local (welcomeText = "Something went wrong, you shouldn't see this :)") local (globeimg, xmlimg, searchimg, checkmarkimg, mediaimg, postbuttonimg)//, editbuttonimg) local (stories) on add (s) htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n"); on decodeEntities (s) s = string.replaceAll (s, "\r\n", "\r") s = string.replaceAll (s, "\n", "\r") return (radio.string.decodeEntities (s, flNeuterJavaScript:false)) on renderGlobe(adr) return ("" + globeimg + "") on renderXmlLink(adr) return("
" + xmlimg + "
") on renderMagglass(adr) if flOneService return("") else local (url, args) new (tabletype, @args) args.xmlUrl = adr^.url if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu url = "?" + webserver.encodeArgs (@args) return(" " + searchimg + "") on renderChannelTitle(adr) return ("") on renderFormButtons() if flOneService && defined (@servicesTable^.[xmlUrl]) // render unsubscribe and delete buttons return ("  ") else // only render delete button return ("") bundle // generate story list. new (tabletype, @stories) local (adrtable = @adrdata^.stories, sizetable = sizeof (adrtable^), i) local (ctstories = 0, lastchanneltitle= "") local (channelnum = 0, storynum = 0) local (thischan) for i = sizetable downto 1 local (adritem = @adrdata^.stories [i], adrservice = @adrdata^.services.[adritem^.url]) bundle //skip stories that are missing, empty, not in selected channel or in bogus service if not defined (adrservice^) continue if not defined (adritem^.storyText) //skip this story -- this can happen if the scan is interrupted continue if (string.trimWhiteSpace (searchEngine.stripMarkup (adrItem^.storyText)) == "") and (not (string.lower (adrItem^.storyText) contains "= ctStoriesToList break if adritem^.channeltitle != lastchanneltitle //display channel title channelnum++ storynum = 0 new (tabletype, @stories.[channelnum]) new (tabletype, @stories.[channelnum].stories) stories.[channelnum].channel = @adrdata^.services.[adritem^.url] lastchanneltitle = adritem^.channeltitle storynum++ stories.[channelnum].stories.[storynum] = adritem ctstories++ bundle // set up default titles and texts pta^.title = radio.string.getlocalizedstring ("aggregator.title") local (t) new (tabletype, @t) t.subscriptionurl = radio.data.systemurls.subscriptionsList welcomeText = radio.string.getlocalizedstring ("aggregator.standardMessage", @t) if flOneService // override defaults if we're displaying one channel pta^.title = "Fish Goat" local (adrservice = @servicesTable^.[xmlUrl]) if defined (adrservice^.compilation.channeltitle) //avoid errors for non-compliant channels pta^.title = "Channel: " + decodeEntities (adrservice^.compilation.channeltitle) local(t) new (tabletype, @t) t.channeltitle = decodeEntities(adrservice^.compilation.channeltitle) welcomeText = radio.string.getlocalizedstring ("aggregator.oneChannelMessage", @t) bundle //precalc img refs local (flSameMachine = pta^.radioResponder.flSameMachine) globeimg = radio.images.systemImageRef ("qbullet/remote", flFileUrl:flSameMachine) xmlimg = radio.images.systemImageRef ("icons/xml", flFileUrl:flSameMachine) searchimg = radio.images.systemImageRef ("qbullet/search", flFileUrl:flSameMachine) checkmarkimg = radio.images.systemImageRef ("icons/checkmark", flFileUrl:flSameMachine) editbuttonimg = radio.images.systemImageRef ("icons/editbutton", flFileUrl:flSameMachine) postbuttonimg = radio.images.systemImageRef ("icons/post", flFileUrl:flSameMachine) postbuttonimg = radio.images.systemImageRef ("icons/post2", flFileUrl:flSameMachine) mediaimg = radio.images.systemImageRef ("qbullet/sound", flFileUrl:flSameMachine) add (""); indentlevel++ add ("") //PBS 01/11/01: name the form, so the script doesn't try to process some other script's form add ("
  " + renderFormButtons() + "
") add(welcomeText) add ("

") add ("
"); indentlevel++ add (""); indentlevel++ local (channelcount = sizeof(stories)) local (i, j) for i = 1 to channelcount local (adrservice = stories.[i].channel) local (adritem = stories.[i].stories.["1"]) add ("") local (itemcount = sizeof(stories.[i].stories)) for j = 1 to itemcount local (adritem = stories.[i].stories.[j]) bundle //add story add (""); indentlevel++ bundle //add checkbox local (name = number (nameof (adritem^))) local (checked = "") if user.radio.prefs.flNewsPageDeleteCheckboxesDefault if ! defined(adritem^.saved) || ! adritem^.saved checked = " checked" add ("") add ("") add ("") bundle //add EDIT button, checkmark local (url) bundle //set url local (args); new (tabletype, @args) if user.radio.prefs.flNewsPageReturnAfterPost //add referer arg to redirect back to this item after posting it to your weblog if pta^.searchargs != "" args.referer = uri + "?" + pta^.searchargs + "#" + i else args.referer = uri + "#" + i args.idStory = number (nameof (adritem^)) url = radio.data.systemUrls.weblogEditor + "?" + webserver.encodeArgs (@args) local (checkmark = "") bundle //an item has a checkmark if it's been blogged if defined (adritem^.adrBlogPost) checkmark = " " + checkmarkimg + "" local (enclosure = "") bundle //if it has an enclosure add a media link if defined (adritem^.enclosure) if not defined (adritem^.enclosure.error) local (url) if defined (adritem^.enclosure.f) url = html.getfileurl (adritem^.enclosure.f) else url = adritem^.enclosure.url enclosure = " " + mediaimg + "" add ("") add (""); indentlevel-- if channelcount == 0 add ("") add ("
 " + renderGlobe(@adrservice^.compilation) + " " + decodeEntities (adrItem^.channelTitle) + ", " + adritem^.time + "." + renderMagglass(adrItem) + "" + renderXmlLink(adritem) + "
  " + adritem^.storytext + "
" + postbuttonimg + "" + checkmark + enclosure + "
There are no stories to list at this time.
"); indentlevel-- add ("
"); indentlevel-- add ("

" + renderFormButtons() + "

") add (""); indentlevel-- return (htmltext) €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€lass=\"dwsTableCell\">There are no stories to list at this time.
"); indentlevel-- add ("
"); indentlevel-- add ("

" + renderFormButtons() + "

") add (""); indentlevel-- return (htmltext) €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€„€€€€€€€€€€em^.enclosure) if not defined (adritem^.enclosure.error) local (url) if defined (adritem^.enclosure.f) url = html.getfileurl (adritem^.enclosure.f) else url = adritem^.enclosure.url enclosure = " " + mediaimg + "" add ("
" + postbuttonimg + "" + checkmark + enclosure + "
") add (""); indentlevel-- if ctstories == 0 add ("There are no stories to list at this time.") add (""); indentlevel-- add (""); indentlevel-- add ("

" + renderFormButtons() + "

") add (""); indentlevel-- return (htmltext) €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€6N±@Ú NGeneva ¹-й.+¾7,LHLANDÿÿÿÿÿÿmac on viewNewsItems (ctStoriesToList = user.radio.prefs.ctStoriesOnNewsPage) local (pta = html.getpagetableaddress ()) local (adrdata = xml.aggregator.init ()) local (flOneService = false, xmlUrl = "") bundle //parse args if defined (pta^.radioResponder.getArgs) local (adrargs = @pta^.radioResponder.getArgs) if defined (adrargs^.xmlUrl) flOneService = true xmlurl = adrargs^.xmlUrl local (adrcache = @adrdata^.cache.[this], adrincache, defaultcachename = "default") if not defined (adrcache^) //make sure the cache table is defined new (tabletype, adrcache) bundle //set adrincache if user.radio.prefs.flCacheNewsItemsPage local (cachename = defaultcachename) if sizeof (xmlUrl) > 0 cachename = xmlUrl if not pta^.radioResponder.flSameMachine cachename = cachename + "Remote" adrincache = @adrcache^.[cachename] bundle //catch post if pta^.method == "POST" local (adrargs = @pta^.radioResponder.postArgs) scratchpad.args = args; edit (@scratchpad.args) if defined (adrargs^.formName) if string.lower (adrargs^.formName) == "editstories" delete (@adrargs^.formName) if defined (adrargs^.unsubscribe) local (args) new (tabletype, @args) args.xmlUrl = xmlUrl if defined (adrdata^.services.[xmlUrl]) if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu local (url = "unsubscribe?" + webserver.encodeargs (@args)) radio.webServer.redirect (url) return ("") local (adrdefaultcache = @adrcache^.[defaultcachename]) for adrarg in adrargs local (s = nameof(adrarg^)) if s beginsWith "listed-" s = string.replace(s, "listed-", "") local (name = string.padwithzeros(number (s), 8)) local (adrstory = @adrdata^.stories.[name]) if defined (adrstory^) adrstory^.saved = true else local (name = string.padwithzeros (number (nameof (adrarg^)), 8)) local (adrstory = @adrdata^.stories.[name]) if defined (adrstory^) adrstory^.saved = false adrdata^.trash.[name] = adrstory^ delete (adrstory) if user.radio.prefs.flCacheNewsItemsPage // posting invalidates the cache. if defined (adrcache^) if defined (adrincache^) //posting invalidates the cache delete (adrincache) if adrdefaultcache == adrincache //02/24/2001 JES: delete the cache for the service if defined (adrstory^) local (adrservicecache = @adrcache^.["xmlUrl=" + string.urlEncode (adrstory^.url)]) if defined (adrservicecache^) delete (adrservicecache) else //02/24/2001 JES: we're on the service page -- delete the default cache if defined (adrdefaultcache^) delete (adrdefaultcache) bundle //see if we can serve from the cache if defined (adrcache^) if defined (adrincache^) return (adrincache^) local (htmltext = aggregatorCategoriesSuite.lib.viewNewsItems.generateHtml(ctStoriesToList, pta, adrdata, flOneService, xmlUrl)) if user.radio.prefs.flCacheNewsItemsPage adrincache^ = htmltext return (htmltext) €€€€€€€€€€€€€„€€€€€€€€€€€€„€€€€€€€€€€€€€„€€€€€€€€€€08:33 PM by DW Only show items with enclosures after the enclosure has been downloaded. 1/19/01; 5:03:23 PM by DW Undo the last change, items with enclosures are visible. Items with enclosures have a media icon, if it's been downloaded, the icon points into the local file system, otherwise it points onto the Web. 1/21/01; 3:47:55 PM by DW Link the EDIT button to myBlog.wsf, instead of addRemove.wsf. 1/24/01; 4:29:55 PM by DW Show a checkmark if the item has an adrBlogPost in its table. 1/27/01; 5:01:03 PM by DW Change the EDIT button to POST. 2/12/01; 4:21:06 PM by PBS Link title for the magnifying glass: "View all stories in the [channel title] channel." 2/12/01; 4:34:35 PM by PBS Fixed bug where quotes and carets in a channel description would mess up rendering -- an example was Dave Winer: Two-Way Web, which has a description of You're soaking in it! ";->" 2/12/01; 5:25:25 PM by PBS Terminology fix -- when viewing one channel, refer to it as a channel, not as a service. Also, use different text at the top of the page when viewing one channel, since the page is *not* showing you the recent stories from all the channels you're subscribed to. Skip empty stories. 2/15/01; 2:49:58 PM by PBS Cleaned up. Mostly removed single-category stuff that was no longer used. Stories that are just images get displayed again. 2/23/01; 10:55:23 AM by PBS Terminology: weblog, not blog. 2/23/01; 4:04:47 PM by PBS Slight change to punctuation in the description at the top of the page. 2/23/01; 10:53:19 PM by JES Linked the Post button to weblog.wsf, instead of myBlog.wsf. 2/24/01; 9:40:04 PM by PBS Help link. 2/24/01; 11:35:08 PM by JES Bug fix: the default cache was not deleted when deleting stories while viewing a single channel. 2/24/01; 11:52:11 PM by JES Fixed cache deletion logic: When deleting an item via either the home page or a service page, delete both the default cache, and the service's cache. 2/25/01; 1:31:32 PM by PBS Set up a second cache for when it's not the same machine. 2/25/01; 2:26:50 PM by JES Separate cache for viewing single channels when it's not the same machine. 3/4/01; 6:11:10 PM by JES Reality check: Don't add the magnifying glass if the service's table is not defined. 3/5/01; 2:14:08 AM by JES Fixed bug where "default" is undefined when deleting a story while accessing the home page remotely. local (pta = html.getpagetableaddress ()) scratchpad.params = pta^ pta^.title = radio.string.getlocalizedstring ("aggregator.title") local (uri = pta^.uri) local (adrdata = xml.aggregator.init ()) local (htmltext = "", indentlevel = 0) on add (s) htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n"); on decodeEntities (s) s = string.replaceAll (s, "\r\n", "\r") s = string.replaceAll (s, "\n", "\r") return (radio.string.decodeEntities (s, flNeuterJavaScript:false)) local (flOneService = false, xmlUrl = "", adrservice) bundle //parse args if defined (pta^.radioResponder.getArgs) local (adrargs = @pta^.radioResponder.getArgs) if defined (adrargs^.xmlUrl) flOneService = true xmlurl = adrargs^.xmlUrl adrservice = @adrdata^.services.[xmlurl] if defined (adrservice^.compilation.channeltitle) //avoid errors for non-compliant channels add ("Channel: " + decodeEntities (adrservice^.compilation.channeltitle) + "

") pta^.title = "Channel: " + decodeEntities (adrservice^.compilation.channeltitle) local (adrcache = @adrdata^.cache.[this], adrincache, defaultcachename = "default") if not defined (adrcache^) //make sure the cache table is defined new (tabletype, adrcache) bundle //set adrincache if user.radio.prefs.flCacheNewsItemsPage local (cachename = defaultcachename) if sizeof (xmlUrl) > 0 cachename = xmlUrl if not pta^.radioResponder.flSameMachine cachename = cachename + "Remote" adrincache = @adrcache^.[cachename] bundle //catch post if pta^.method == "POST" local (adrargs = @pta^.radioResponder.postArgs) scratchpad.args = args; edit (@scratchpad.args) if defined (adrargs^.formName) if string.lower (adrargs^.formName) == "editstories" delete (@adrargs^.formName) if defined (adrargs^.unsubscribe) local (args) new (tabletype, @args) args.xmlUrl = xmlUrl if defined (adrdata^.services.[xmlUrl]) if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu local (url = "unsubscribe?" + webserver.encodeargs (@args)) radio.webServer.redirect (url) return ("") local (adrdefaultcache = @adrcache^.[defaultcachename]) for adrarg in adrargs local (name = string.padwithzeros (number (nameof (adrarg^)), 8)) local (adrstory = @adrdata^.stories.[name]) if defined (adrstory^) adrdata^.trash.[name] = adrstory^ delete (adrstory) if user.radio.prefs.flCacheNewsItemsPage if defined (adrcache^) if defined (adrincache^) //posting invalidates the cache delete (adrincache) if adrdefaultcache == adrincache //02/24/2001 JES: delete the cache for the service if defined (adrstory^) local (adrservicecache = @adrcache^.["xmlUrl=" + string.urlEncode (adrstory^.url)]) if defined (adrservicecache^) delete (adrservicecache) else //02/24/2001 JES: we're on the service page -- delete the default cache if defined (adrdefaultcache^) delete (adrdefaultcache) bundle //see if we can serve from the cache if defined (adrcache^) if defined (adrincache^) return (adrincache^) htmltext = aggregatorCategoriesSuite.lib.viewNewsItems.generateHtml(ctStoriesToList, pta, adrdata, flOneService, xmlUrl) if user.radio.prefs.flCacheNewsItemsPage adrincache^ = htmltext return (htmltext) €„€€€€€€€€€€€€€€€€€€€€€€„€€„€„„€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€„€€€€€td valign=\"top\">  ") bundle //message at the top of the page if flOneService local (t) new (tabletype, @t) t.channeltitle = decodeEntities (adrservice^.compilation.channeltitle) add (radio.string.getlocalizedstring ("aggregator.oneChannelMessage", @t)) else local (t) new (tabletype, @t) t.subscriptionurl = radio.data.systemurls.subscriptionsList add (radio.string.getlocalizedstring ("aggregator.standardMessage", @t)) add (radio.string.getlocalizedstring ("aggregator.clickThePostButton")) if user.radio.prefs.flNewsPageDeleteCheckboxesDefault add (radio.string.getlocalizedstring ("aggregator.checkBoxesOnIntro")) else add (radio.string.getlocalizedstring ("aggregator.checkBoxesOffIntro")) if flOneService add (radio.string.getlocalizedstring ("aggregator.howToUnsubscribe")) add (" " + radio.userinterface.helpLink ("The News Aggregator page")) add ("

") add ("
"); indentlevel++ add (""); indentlevel++ local (adrtable = @adrdata^.stories, sizetable = sizeof (adrtable^), i) local (lastchanneltitle = "", ctstories = 0) for i = sizetable downto 1 local (adritem = @adrdata^.stories [i]) bundle //skip missing or empty stories if not defined (adritem^.storyText) //skip this story -- this can happen if the scan is interrupted continue if (string.trimWhiteSpace (searchEngine.stripMarkup (adrItem^.storyText)) == "") and (not (string.lower (adrItem^.storyText) contains " ctStoriesToList break if adritem^.channeltitle != lastchanneltitle //display channel title local (globe = "") bundle //link the globe to the HTML rendering of the channel with adrservice^.compilation globe = "" + globeimg + "" //PBS 02/12/01: fix bug where quotes and carets in a channel description would mess up rendering -- an example was Dave Winer: Two-Way Web, which has a description of You're soaking in it! ";->" local (xmllink) bundle //link the XML icon to the source XML file for the channel xmllink = "
" + xmlimg + "
" local (magglass = "") bundle //load up the magnifying glass with some HTML if not flOneService local (url, args) new (tabletype, @args) args.xmlUrl = adritem^.url if defined (pta^.radioResponder.getArgs.menu) args.menu = pta^.radioResponder.getArgs.menu url = "?" + webserver.encodeArgs (@args) magglass = " " + searchimg + "" add ("") lastchanneltitle = adritem^.channeltitle bundle //add story add (""); indentlevel++ bundle //add checkbox local (name = number (nameof (adritem^))) local (checkboxval = "xxx ") if user.radio.prefs.flNewsPageDeleteCheckboxesDefault checkboxval = checkboxval + "checked" add ("") add ("") add ("") bundle //add EDIT button, checkmark local (url) bundle //set url local (args); new (tabletype, @args) if user.radio.prefs.flNewsPageReturnAfterPost //add referer arg to redirect back to this item after posting it to your weblog if pta^.searchargs != "" args.referer = uri + "?" + pta^.searchargs + "#" + i else args.referer = uri + "#" + i args.idStory = number (nameof (adritem^)) url = radio.data.systemUrls.weblogEditor + "?" + webserver.encodeArgs (@args) local (checkmark = "") bundle //an item has a checkmark if it's been blogged if defined (adritem^.adrBlogPost) checkmark = " " + checkmarkimg + "" local (enclosure = "") bundle //if it has an enclosure add a media link if defined (adritem^.enclosure) if not defined (adritem^.enclosure.error) local (url) if defined (adritem^.enclosure.f) url = html.getfileurl (adritem^.enclosure.f) else url = adritem^.enclosure.url enclosure = " " + mediaimg + "" add ("") add (""); indentlevel-- if ctstories == 0 add ("") add ("
 " + globe + " " + decodeEntities (adrItem^.channelTitle) + ", " + adritem^.time + "." + magglass + "" + xmllink + "
  " + adritem^.storytext + "
  " + decodeEntities (adritem^.storytext) + "
" + postbuttonimg + "" + checkmark + enclosure + "
There are no stories to list at this time.
"); indentlevel-- add ("
"); indentlevel-- local (flDeleteButtonAdded = false) if flOneService if defined (adrservice^) add ("

  

") flDeleteButtonAdded = true if not flDeleteButtonAdded add ("

") add (""); indentlevel-- if user.radio.prefs.flCacheNewsItemsPage adrincache^ = htmltext return (htmltext) €„€„€€€€€€€€€€€€€€€€€€„€€„„„„„„„„„„„„„„„„„„„„€€€N±