Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.radio.thread.agents.installer
<<Changes:
<<12/13/02; 11:59:34 AM by DW
<<Create gems/rsd.xml if it doesn't exist.
<<3/19/02; 5:39:55 PM by JES
<<Only read defaultCloud.xml and get initialResources, if user.radio.prefs.usernum is not defined.
<<3/19/02; 5:00:23 PM by JES
<<Make sure that user.radio.stats.flGetInitialResources is defined.
<<3/19/02; 3:50:00 PM by JES
<<Always get initial resources, even for UserLand's RCS, otherwise Themes and initial RSS subscriptions aren't correct.
<<3/11/02; 4:04:23 PM by JES
<<Delete radio.bootstrap (obsolete), radio.getInitialResources and radio.registerWithServer (both are now in the radio.cloud sub-table).
<<3/11/02; 1:13:53 AM by JES
<<Only get initial resources if user.radio.prefs.defaultCloud.server is not radio.xmlsotragesystem.com.
<<3/11/02; 1:11:14 AM by JES
<<If defaultCloud.xml is present in the Radio folder, call getInitialResources here, before the rest of Radio's initialization has taken place.
<<3/11/02; 12:17:29 AM by JES
<<If the defaultCloud.xml file is present, and we've never called getInitialResources, call it here. This is the bottleneck for the bootstrapping of a fresh Radio install into a given RCS server.
<<3/2/02; 4:39:53 PM by JS
<<Set up user.radio.prefs.defaultCloud and user.radio.prefs.rssCloud, if the defaultCloud.xml file is present. Don't do the aggregator bootstrap here. This now happens in radio.bootstrap.
<<Commented out invalidation of the file cache. This was only used during the beta process, and cannot affect post 8.0 release users -- it can only cause development confusion later on.
<<2/13/02; 11:21:02 PM by JES
<<Call radio.weblog.utilities.fixCategoryNameDirectives to make sure that a #prefs.txt file containing an appropriate #categoryName directive, exists in each category's folder.
<<1/22/02; 8:16:08 PM by JES
<<Call radio.userInterface.saveImages to save any new system image files.
<<1/7/02; 9:37:38 PM by PBS
<<Set updates server to radioupdates.userland.com.
<<1/3/02; 4:28:24 PM by DW
<<Nuke "playlist" stuff.
<<12/31/01; 6:52:15 PM by JES
<<Call radio.theme.updateThemes ().
<<12/29/01; 5:28:16 PM by JES
<<Make sure user.radio.prefs.rssCloud.server points at radio.xmlstoragesystem.com.
<<12/21/01; 5:25:30 PM by JES
<<Delete radio.data.homeFolderTextFiles.["stories/newStory.txt"], and the corresponding file on disk.
<<12/20/01; 1:48:07 PM by JES
<<Empty the table at radio.data.website.["#glossary"].
<<12/19/01; 11:40:08 PM by JES
<<Call webBrowser.init, to set up proxy settings (in particular, user.webBrowser.proxy.enabled).
<<12/13/01; 5:54:01 PM by JES
<<On MacOS X, hard-code the path to the text editor, to the path to TextEdit. This is necessary because file.findApplication doesn't find the app properly. It will be in the same location on 99% of systems. If it's not there, do what we used to, which is call file.findApplication ('ttxt') which finds SimpleText.
<<12/11/01; 5:39:16 PM by DW
<<Delete all entries in user.radio.settings.files whose files don't exist.
<<12/10/01; 1:05:48 PM by JES
<<Make sure flRenderHtml is defined for all categories.
<<12/10/01; 1:03:07 AM by JES
<<Init user.radio.prefs.editors.["text/xml"] to edit in Radio.
<<12/6/01; 12:26:56 AM by JES
<<Don't delete radio.data.homeFolderTextFiles.["index.txt"].
<<12/3/01; 9:47:22 PM by JES
<<Init user.radio.prefs.editors.
<<12/1/01; 12:25:16 AM by JES
<<Reset the menubar.
<<Changes before 12/1/01
<<11/30/01; 12:56:29 PM by JES
<<Delete radio.data.reinstallHomeFolderFiles.
<<11/28/01; 6:44:32 PM by DW
<<Scan over the files table, deleting filetext and outlineAsString for each sub-table.
<<11/28/01; 11:35:34 AM by JES
<<Delete radio.data.homeFolderTextFiles.["index.txt"].
<<11/27/01; 7:08:30 PM by JES
<<Delete radio.data.systemFolderTextFiles.["pages/weblog.txt"].
<<11/27/01; 12:58:47 AM by JES
<<Install the address of the radio.callbacks.installTool callback at user.tools.callbacks.afterInstall.radio.
<<11/26/01; 12:37:48 PM by JES
<<Delete radio.data.homeFolderTextFiles.["#javaScript.txt"].
<<11/26/01; 12:47:10 AM by JES
<<Make sure the websiteFramework responder is installed.
<<11/25/01; 8:47:01 AM by DW
<<Pass a url to xml.aggregator.bootstrap, it's no longer hard-coded in the script.
<<11/25/01; 4:25:35 AM by JES
<<Delete obsolete help pages from radio.data.systemFolderTextFiles.
<<11/23/01; 1:08:04 PM by JES
<<Make sure the manilaEdit responder is installed.
<<11/23/01; 12:28:47 PM by JES
<<Delete user.webserver.responders.websiteFramework.data.docTree.UserLand if it points at myUserLandWebsite.
<<11/21/01; 6:48:38 PM by JES
<<If user.webserver.postFilters.addToServerLog references the old playlist script, delete it. It will be recreated, pointing at the new location, the next time radio.init runs.
<<11/21/01; 6:28:40 PM by JES
<<Delete radio.utilities.smurfTurfInstaller and radio.utilities.smurfTurfFinishInstall.
<<11/21/01; 6:10:16 PM by JES
<<Delete radio.data.homeFolderTextFiles.["#cascadingStyleSheet.txt"]
<<11/21/01; 5:32:20 PM by JES
<<Delete radio.data.homeFolderTextFiles.["#navigatorLinks.txt"]
<<11/20/01; 2:42:28 PM by JES
<<Fixed an error "password has not been defined". Don't hard-code the path to the usptream folder -- get the path from user.radio.prefs.upstream.folder.
<<11/20/01; 3:30:01 AM by JES
<<Changed defaultXssPassword to default. If user.radio.prefs.passwords.default is not defined, set it to the value of user.radio.prefs.passwords.defaultXssPassword.
<<11/19/01; 7:23:49 PM by JES
<<Delete objects from radio.data.systemFolderTextFiles, that correspond to obsolete system folder files. Delete obsolete scripts in the radio.weblog table.
<<11/14/01; 3:16:36 PM by DW
<<Delete radio.userInterface.helpText.
<<11/8/01; 12:14:11 PM by DW
<<Call xml.aggregator.bootstrap instead of radio.utilities.readVirginServices.
<<11/4/01; 11:36:17 PM by JES
<<If radio.data.flDoInitialScan is true, run the first news scan in its own thread.
<<10/31/01; 2:57:22 PM by JES
<<Delete user.radio.stats.flNotifyWorkgroupOfNewStory if defined.
<<10/30/01; 7:37:45 PM by DW
<<Comment code that gets rid of broken urls in categories.
<<Once gotten rid of they are no longer broken.
<<10/30/01; 6:23:58 PM by JES
<<Delete radio.aggregator.readAllServices, if defined.
<<10/28/01; 11:56:19 AM by DW
<<Delete htmlUrl in all the categories, this unhots the category names on the home page (the URLs were probably wrong), and they will be reset when the category is published.
<<10/19/01; 3:06:28 AM by JES
<<Delete obsolete items: radio.thread.agents.generateOutputChannels and radio.weblog.generateOutputChannels.
<<9/24/01; 11:27:02 PM by JES
<<Re-install system folder text files.
<<9/24/01; 2:53:19 PM by JES
<<Install home folder text files. This makes sure all the files exist, and upgrades macros if needed.
<<8/27/01; 12:58:23 AM by JES
<<Cross-platform support for the #ftpSite.folder folder. (Path delimiters were hard-coded to the backslash character.)
if radio.data.flinstall {
if not defined (user.radio.prefs.usernum) { //read defaultCloud.xml, get initialResources from the RCS
bundle { //defaultCloud
local (f = frontier.pathString + "defaultCloud.xml");
if file.exists (f) {
local (xtext = file.readWholeFile (f));
table.xmlToTable (xtext, @user.radio.prefs.defaultCloud)};
if not defined (user.radio.stats.flGetInitialResources) {
user.radio.stats.flGetInitialResources = true};
if user.radio.stats.flGetInitialResources {
radio.cloud.getInitialResources ();
user.radio.stats.flGetInitialResources = false;
bundle { //default the rssCloud and webBugSimulator to the same server as the default cloud
user.radio.prefs.rssCloud.server = user.radio.prefs.defaultCloud.server;
user.radio.prefs.rssCloud.port = user.radio.prefs.defaultCloud.port;
user.radio.prefs.rssCloud.protocol = user.radio.prefs.defaultCloud.protocol;
user.radio.prefs.rssCloud.rpcPath = user.radio.prefs.defaultCloud.rpcPath;
user.radio.prefs.webBugSimulator.server = user.radio.prefs.defaultCloud.server;
user.radio.prefs.webBugSimulator.port = user.radio.prefs.defaultCloud.port;
user.radio.prefs.webBugSimulator.rpcPath = user.radio.prefs.defaultCloud.rpcPath}}};
bundle { //rssCloud
local (f = frontier.pathString + "rssCloud.xml");
if file.exists (f) {
local (xtext = file.readWholeFile (f));
table.xmlToTable (xtext, @user.radio.prefs.rssCloud)}};
bundle { //webBugSimulator
local (f = frontier.pathString + "webBugSimulator.xml");
if file.exists (f) {
local (xtext = file.readWholeFile (f));
table.xmlToTable (xtext, @user.radio.prefs.webBugSimulator)}}};
webBrowser.init ();
bundle { //delete all entries in user.radio.settings.files whose files don't exist
local (i, adrfile, f);
for i = sizeof (user.radio.settings.files) downto 1 {
adrfile = @user.radio.settings.files [i];
if not file.exists (nameof (adrfile^)) {
delete (adrfile)}}};
if defined (user.webserver.prefs.ext2MIME.fttb) {
if user.webserver.prefs.ext2MIME.fttb == "text/html" { //seriously wrong
user.webserver.prefs.ext2MIME.fttb = "application/x-frontier-tabl"}};
bundle { //init the website
local (adrsite = @radio.data.website);
if system.environment.isWindows { //set addLineFeeds pref if on Windows
adrsite^.["#prefs"].addLinefeeds = true};
bundle { //set the #ftpSite table, as a local site, contained within the parent site, or the Websites folder
local (pc = file.getPathChar ());
adrsite^.["#ftpSite"].folder = file.getSpecialFolderPath ("", "temp", true) + "UserLand" + pc + "radioServer" + pc;
adrsite^.["#ftpSite"].url = file.fileToURL (adrsite^.["#ftpSite"].folder)};
if sizeOf (adrsite^.["#glossary"]) > 0 {
table.emptyTable (@adrsite^.["#glossary"])}};
bundle { //make sure flRenderHtml is defined for all categories
local (adrcat, adrdata = radio.weblog.init ());
for adrcat in @adrdata^.categories {
if not defined (adrcat^.flRenderHtml) {
adrcat^.flRenderHtml = false}}};
bundle { //make sure user.radio.prefs.rssCloud.server points at radio.xmlstoragesystem.com
if not defined (user.radio.settings.flCheckedRssCloud) {
if string.lower (user.radio.prefs.rssCloud.server) == "data.ourfavoritesongs.com" {
user.radio.prefs.rssCloud.server = "radio.xmlstoragesystem.com"};
user.radio.settings.flCheckedRssCloud = true}};
bundle { //init user.radio.prefs.editors
if not defined (user.radio.prefs.editors.["text/x-opml"]) {
user.radio.prefs.editors.["text/x-opml"] = Frontier.getProgramPath ()};
if not defined (user.radio.prefs.editors.["text/plain"]) {
local (editor);
if system.environment.isMac {
local (f = file.getSystemDisk () + "Applications:TextEdit.app:");
if file.exists (f) {
editor = f}
else {
editor = file.findApplication ('ttxt')}}
else { //windows
editor = file.findApplication ("txt")};
if editor {
user.radio.prefs.editors.["text/plain"] = editor}};
if not defined (user.radio.prefs.editors.["text/xml"]) {
user.radio.prefs.editors.["text/xml"] = Frontier.getProgramPath ()}};
bundle { //delete obsolete stuff
if defined (user.radio.prefs.upstream.extensions) {
delete (@user.radio.prefs.upstream.extensions)};
if defined (user.radio.nodeTypes) {
delete (@user.radio.nodeTypes)};
if defined (user.radio.prefs.ctStoriesOnHomePage) {
if not defined (user.radio.prefs.ctStoriesOnNewsPage) {
user.radio.prefs.ctStoriesOnNewsPage = user.radio.prefs.ctStoriesOnHomePage};
delete (@user.radio.prefs.ctStoriesOnHomePage)};
if defined (radio.thread.agents.generateOutputChannels) {
delete (@radio.thread.agents.generateOutputChannels)};
if defined (radio.weblog.generateOutputChannels) {
delete (@radio.weblog.generateOutputChannels)};
if defined (radio.aggregator.readAllServices) {
delete (@radio.aggregator.readAllServices)};
if defined (user.radio.stats.flNotifyWorkgroupOfNewStory) {
delete (@user.radio.stats.flNotifyWorkgroupOfNewStory)};
if defined (radio.userInterface.helpText) {
delete (@radio.userInterface.helpText)};
if defined (radio.data.homeFolderTextFiles.["#navigatorLinks.txt"]) {
delete (@radio.data.homeFolderTextFiles.["#navigatorLinks.txt"])};
if defined (radio.data.homeFolderTextFiles.["#javaScript.txt"]) {
delete (@radio.data.homeFolderTextFiles.["#javaScript.txt"])};
if defined (radio.data.homeFolderTextFiles.["#cascadingStyleSheet.txt"]) {
delete (@radio.data.homeFolderTextFiles.["#cascadingStyleSheet.txt"])};
if defined (radio.data.homeFolderTextFiles.["stories/newStory.txt"]) {
delete (@radio.data.homeFolderTextFiles.["stories/newStory.txt"]);
if file.exists (radio.file.getAbsolutePath ("/stories/newStory.txt")) {
try {file.delete (radio.file.getAbsolutePath ("/stories/newStory.txt"))}}};
if defined (radio.data.reinstallHomeFolderFiles) {
radio.data.flReinstallHomeFolderFiles = radio.data.reinstallHomeFolderFiles;
delete (@radio.data.reinstallHomeFolderFiles)};
if defined (radio.bootstrap) {
delete (@radio.bootstrap)};
if defined (radio.getInitialResources) {
delete (@radio.getInitialResources)};
if defined (radio.registerWithServer) {
delete (@radio.registerWithServer)};
if defined (radio.utilities.smurfTurfInstaller) {
delete (@radio.utilities.smurfTurfInstaller)};
if defined (radio.utilities.smurfTurfFinishInstall) {
delete (@radio.utilities.smurfTurfFinishInstall)};
if defined (user.webserver.postFilters.addToServerLog) {
if string (user.webserver.postFilters.addToServerLog) contains "playlist" {
delete (@user.webserver.postFilters.addToServerLog)}};
bundle { //delete obsolete scripts in the radio.weblog table
if defined (radio.weblog.main) {
delete (@radio.weblog.main)};
if defined (radio.weblog.publishArchivePages) {
delete (@radio.weblog.publishArchivePages)};
if defined (radio.weblog.publishInThread) {
delete (@radio.weblog.publishInThread)};
if defined (radio.weblog.publishStaticArchivePages) {
delete (@radio.weblog.publishStaticArchivePages)};
if defined (radio.weblog.publishStaticHomePage) {
delete (@radio.weblog.publishStaticHomePage)};
if defined (radio.weblog.publishStaticPage) {
delete (@radio.weblog.publishStaticPage)};
if defined (radio.weblog.updateStaticPagesForDates) {
delete (@radio.weblog.updateStaticPagesForDates)};
if defined (radio.weblog.updateStaticPagesForPost) {
delete (@radio.weblog.updateStaticPagesForPost)};
if defined (radio.weblog.uploadFile) {
delete (@radio.weblog.uploadFile)};
if defined (radio.weblog.uploadImage) {
delete (@radio.weblog.uploadImage)};
if defined (radio.weblog.uploadManila) {
delete (@radio.weblog.uploadManila)}};
bundle { //delete old objects from radio.data.systemFolderTextFiles
local (adrtable = @radio.data.systemFolderTextFiles);
on deleteItem (name) {
if defined (adrtable^.[name]) {
delete (@adrtable^.[name])}};
deleteItem ("misc/editorsOnlyMenu.opml");
deleteItem ("misc/prefsWizard.opml");
deleteItem ("misc/prefsWizardBasic.opml");
deleteItem ("misc/prefsWizardReading.opml");
deleteItem ("misc/prefsWizardServer.opml");
deleteItem ("misc/prefsWizardUpstreamFtp.opml");
deleteItem ("misc/prefsWizardUpstreamXss.opml");
deleteItem ("misc/prefsWizardWeblog.opml");
deleteItem ("pages/prefsBasic.txt");
deleteItem ("pages/prefsPasswords.txt");
deleteItem ("pages/prefsReading.txt");
deleteItem ("pages/prefsServer.txt");
deleteItem ("pages/prefsWeblog.txt");
deleteItem ("pages/setup.txt");
deleteItem ("pages/weblog.txt");
deleteItem ("templates/folderBrowser.txt");
deleteItem ("templates/webServerError.txt");
deleteItem ("help/blogPost.opml");
deleteItem ("help/categories.opml");
deleteItem ("help/news.opml");
deleteItem ("help/prefs.opml");
deleteItem ("help/subscriptions.opml");
deleteItem ("help/weblog.opml")};
if defined (user.webserver.responders.websiteFramework.data.docTree.UserLand) {
if string (user.webserver.responders.websiteFramework.data.docTree.UserLand) endsWith "myUserLandWebsite" {
delete (@user.webserver.responders.websiteFramework.data.docTree.UserLand)}}};
bundle { //delete "playlist" stuff (all obsolete)
if defined (system.shutdown.playlist) {
delete (@system.shutdown.playlist)};
if defined (user.callbacks.closeWindow.manilaSite) {
delete (@user.callbacks.closeWindow.manilaSite)};
if defined (user.betty.rpcHandlers.playlist) {
delete (@user.betty.rpcHandlers.playlist)}};
bundle { //init the #upstream.xml file, based on items at user.playlist
if defined (user.playlist.prefs.account) {
local (folder = user.radio.prefs.upstream.folder);
file.sureFolder (folder);
local (f = folder + radio.data.fileNames.upstreamFileName);
if not file.exists (f) {
local (account = user.playlist.prefs.account.email);
local (name = user.playlist.prefs.account.name);
if not defined (user.radio.prefs.passwords.default) {
if defined (user.radio.prefs.passwords.defaultXssPassword) {
user.radio.prefs.passwords.default = user.radio.prefs.passwords.defaultXssPassword}
else {
user.radio.prefs.passwords.default = ""}};
if user.radio.prefs.passwords.default == "" {
if defined (user.playlist.prefs.account.password) {
user.radio.prefs.passwords.default = user.playlist.prefs.account.password}};
radio.upstream.builtinDrivers.xmlStorageSystem.saveUpstreamSpec (f, account, name, "default")}};
bundle { //make there's at least one #upstream.xml in system/upstream, regardless of transference of playlist prefs
if not defined (user.radio.prefs.passwords.default) {
if defined (user.radio.prefs.passwords.defaultXssPassword) {
user.radio.prefs.passwords.default = user.radio.prefs.passwords.defaultXssPassword}
else {
user.radio.prefs.passwords.default = ""}};
local (f = user.radio.prefs.upstream.folder + radio.data.fileNames.upstreamFileName);
if not file.exists (f) {
radio.upstream.builtinDrivers.xmlStorageSystem.saveUpstreamSpec (f, user.prefs.mailaddress, user.prefs.name, "default")}}};
bundle { //maintenence of the file cache
<<bundle //invalidate file cache for versions prior to 1.0a1
<<This forces everything to be re-upstreamed so the urls will be set properly
<<Previous versions didn't do a good job of maintaining urls.
<<if not defined (user.radio.settings.fileCacheVersion)
<<local (adr)
<<for adr in @user.radio.settings.files
<<adr^.modified = date (0)
<<adr^.upstream.url = ""
<<adr^.upstream.whenLastUploaded = date (0)
bundle { //set the filecache version
user.radio.settings.fileCacheVersion = radio.data.version}};
bundle { //disable pre-7.1 threads
<<bundle //old code which doesn't work because myUserLandSuite.init and playlist.init just reinstall the threads
<<try {delete (@user.scheduler.threads.MyUserLand)}
<<try {delete (@user.scheduler.threads.playlist)}
on disableThread (adrthread) {
try {
while typeOf (adrthread^) == addressType {
adrthread = adrthread^};
try {
adrthread^.enabled = false}}};
disableThread (@user.scheduler.threads.MyUserLand);
disableThread (@user.scheduler.threads.playlist);
scheduler.monitorThreads ()}; //make sure the disabled threads get killed
bundle { //make sure image files are installed
radio.userInterface.saveImages ()};
bundle { //make sure home & system folder text files are installed
radio.utilities.homeFolderTextFiles.install ();
radio.utilities.systemFolderTextFiles.install ()};
bundle { //make sure the manilaEdit responder is installed
if not defined (user.webserver.responders.manilaEdit) {
manila.editResponder.init ()}};
bundle { //make sure the websiteFramework responder is installed
if not defined (user.webserver.responders.websiteFramework) {
user.webserver.responders.websiteFramework = webserver.data.responders.websiteFramework;
if defined (user.webserver.responders.websiteFramework.data.docTree.allsites) {
delete (@user.webserver.responders.websiteFramework.data.docTree.allsites)};
if defined (user.webserver.responders.websiteFramework.data.docTree.contents) {
delete (@user.webserver.responders.websiteFramework.data.docTree.contents)}};
if defined (user.webserver.responders.websiteFramework.data.prefs.ODBDefault) {
if typeOf (user.webserver.responders.websiteFramework.data.prefs.ODBDefault) == listType {
if not (user.webserver.responders.websiteFramework.data.prefs.ODBDefault contains "index") {
user.webserver.responders.websiteFramework.data.prefs.ODBDefault = user.webserver.responders.websiteFramework.data.prefs.ODBDefault + "index"}}}};
bundle { //install callbacks
if not defined (user.tools.callbacks.afterInstall.radio) {
user.tools.callbacks.afterInstall.radio = @radio.callbacks.installTool}};
<<bundle //get rid of broken urls in categories
<<They'll be re-set when the user publishes a category, in radio.weblog.publishCategoryRss.
<<local (adrblog = radio.weblog.init (), adrcat)
<<for adrcat in @adrblog^.categories
<<try {delete (@adrcat^.htmlUrl)}
bundle { //delete filetext, outlineAsString in file cache
local (adr);
for adr in @user.radio.settings.files {
if defined (adr^.filetext) {
delete (@adr^.filetext)};
if defined (adr^.outlineAsString) {
delete (@adr^.outlineAsString)}}};
bundle { //reset menu bar
menu.noSuite ()};
<<bundle //download Themes
<<if not tcp.isOffline ()
<<thread.callScript (@radio.theme.updateThemes, {})
bundle { //set updates server to radioupdates.userland.com
if string.lower (user.rootUpdates.servers.Radio.server) == "updates.braincase.net" {
user.rootUpdates.servers.Radio.server = "radioupdates.userland.com"}};
bundle { //make sure categories' #prefs.txt files exist
radio.weblog.utilities.fixCategoryNameDirectives (radio.weblog.init ())};
bundle { //create gems/rsd.xml if it doesn't exist, 12/13/02 by DW
local (f);
radio.init ();
f = radio.file.getAbsolutePath (user.radio.prefs.rsdXmlFilePath);
file.surefilepath (f);
if not file.exists (f) {
radio.weblog.writeRsdFile (f)}};
radio.data.flinstall = false}
<<if radio.data.flDoInitialScan //read default subscriptions, and run the first news scan
<<radio.data.flDoInitialScan = false
<<thread.callScript (@xml.aggregator.bootstrap, {radio.data.cloudUrls.aggregatorBootstrap})
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.