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

system.verbs.builtins.radio.html.setupRadio

on setupRadio () {
	<<Changes
		<<3/16/02; 1:36:01 AM by JES
			<<Call radio.cloud.registerWithServer when connecting an existing user, as well as when connecting a new user.
		<<3/11/02; 5:43:59 PM by JES
			<<Call radio.cloud.registerWithServer, instead of radio.registerWithServer. It's the same code, but in a new location.
		<<3/10/02; 11:42:32 PM by JES
			<<Call radio.registerWithServer to register, instead of radio.bootstrap. The getInitialResources code has been factored, and now happens before the setup page is ever loaded.
		<<3/2/02; 4:00:12 PM by JES
			<<Call through radio.bootstrap, once we have enough information from the user to connect to the cloud. radio.bootstrap knows how to connect to an arbitrary community, instead of only connecting to radio.xmlstoragesystem.com.
			<<Also, no longer require that usernums be greater than 999. Only require that they be a positive integer.
		<<1/16/02; 2:50:33 AM by JES
			<<After writing the upstream spec to disk, but before turning on upstreaming, set whenLastUpstreamed for all files in the www folder to "now" plus one second. This prevents any files from being upstreamed after instaling. The server already has a placeholder page, and the user should see that page, until they post an item to their weblog.
		<<12/31/01; 12:18:19 PM by PBS
			<<The checkbox for enabling/disabling using a proxy server now works.
		<<12/24/01; 3:22:59 PM by JES
			<<Redirect to the home page after displaying the confirmation page.
		<<12/21/01; 1:57:32 AM by JS
			<<Rewrote the POST handling code to handle the new all-on-one-page forms.
			<<Added proxy settings to the replacement-table passed in to radio.string.getlocalizedstring, when rendering the page.
			<<Added error and confirmation messages.
			<<Don't keep the user out of the page if they already have a usernum -- let them fill out the form and get the confirmation.
		<<12/19/01; 5:50:37 PM by DW
			<<Overhaul. Many changes.
			<<The htmltext for the various forms is here: radio.data.localization.languages.english.strings.setupRadio.main.
		<<12/5/01; 10:21:44 PM by JES
			<<Get the filetable for index.txt, and set its upstream.whenLastUpstreamed to 1 second after the mod-date of the file. This prevents the first upstreaming of the file, preserving the place-holder home page in the cloud.
		<<12/5/01; 4:36:05 PM by JES
			<<Fixed a bug where registered users who were entering their usernum and password would get the Already Set Up page instead of the registered user Wecome page.
		<<12/4/01; 11:24:14 PM by JES
			<<If we already have a usernum, don't let the user get another one.
		<<11/30/01; 1:18:55 AM by JES
			<<Fixed an error where if Radio.root was updated while the setup form was running in the browser, that the user would get an error message about organization being undefined.
		<<11/29/01; 3:57:41 PM by JES
			<<Rewrite: There are now two pages, one for new users and one for users who already have a usernum. After submitting either, you see a confirmation page. Clicking Continue at the bottom of the confirmation page takes you to the home page.
		<<11/28/01; 11:47:30 PM by JES
			<<Localized.
		<<11/21/01; 11:25:12 PM by JES
			<<Clarified instructions about usernums and passwords.
		<<11/21/01; 7:46:29 PM by JES
			<<Store password as a binary, instead of as a string.
		<<11/20/01; 3:27:14 AM by JES
			<<Changed user.radio.prefs.passwords.defaultXssPassword to user.radio.prefs.passwords.default.
		<<11/8/01; 2:32:48 AM by JES
			<<If this is a Mac, convert the name from latin text to mac text.
		<<11/3/01; 1:33:27 AM by JES
			<<Revised the explanatory text.
		<<11/1/01; 6:02:00 PM by JES
			<<The Radio 7.1 setup page -- gets enough user information to register with the cloud. Allows existing users who are already registered to enter their usernum.
	local (fldebugging = false); //turn this off before releasing
	
	local (pta = html.getPageTableAddress ());
	if fldebugging { //copy the pagetable to scratchpad.params
		scratchpad.params = pta^; edit (@scratchpad.params)};
	pta^.title = radio.string.getLocalizedString ("setupRadio.title");
	local (adrblog = radio.weblog.init ());
	bundle { //kludge the weblog title -- [more comments below]
		<<We know the title is initialized by radio.weblog.init to "'s Radio Weblog", so we fix it here, and then put the user's name in once we have it. [JES]
			<<The thing is that rdio.weblog.init uses user.prefs.name to initialize weblogData.prefs.title, but user.prefs.name is the empty string when Radio is first launched.
		if adrblog^.prefs.title == "'s Radio Weblog" {
			adrblog^.prefs.title = "My Radio Weblog";
			radio.webserver.redirect (pta^.path);
			return ("")}};
	
	local (upstreamDriverName = "xmlStorageSystem");
	
	local (htmltext, indentlevel = 0);
	on add (s) {
		htmltext = htmltext + string.filledstring ("\t", indentlevel) + s + "\r"};
	
	bundle { //set up a temp table to save messages for redirected pages
		if not defined (system.temp.radio.setupRadio) {
			new (tableType, @system.temp.radio.setupRadio)}};
	
	local (errorMessage = "", confirmMessage = "", postedSection = "", flError = false, flConfirmPage);
	if pta^.method == "POST" {
		local (adrargs = @pta^.radioResponder.postArgs);
		
		on getInitials (s) {
			local (initials = "");
			bundle { //strip off parentheticals
				if s contains "(" {
					s = string.nthField (s, "(", 1)};
				if s contains "[" {
					s = string.nthField (s, "[", 1)};
				if s contains "{" {
					s = string.nthField (s, "{", 1)}};
			s = string.trimWhiteSpace (s);
			initials = string.upper (s[1]);
			local (i, ct = sizeOf (s));
			if sizeOf (s) > 1 {
				local (flNextCharIsInitial = false);
				for i = 2 to ct {
					if flNextCharIsInitial {
						if string.isAlpha (s[i]) {
							initials = initials + string.upper (s[i])};
						flNextCharIsInitial = false};
					if not string.isAlpha (s[i]) {
						flNextCharIsInitial = true}}};
			return (initials)};
		on setName (name) {
			user.prefs.name = name;
			if adrblog^.prefs.title == "My Radio Weblog" { //work around a chicken-and-egg problem
				<<The problem & the solution:
					<<radio.thread.agents.mailToWeblog calls radio.weblog.checkMail, which in turn calls radio.weblog.init.
					<<(There may be other places radio.weblog.init is called before we get here as well.)
					<<This happens before we ever get to the desktop website, so you end up with a weblog whose title is "'s Radio Weblog".
					<<Solution: Set user.prefs.name, delete the title, and let radio.weblog.init re-create it.
				delete (@adrblog^.prefs.title);
				radio.weblog.init ()};
			weblogData.prefs.authorName = name;
			bundle { //set user.prefs.initials
				user.prefs.initials = getInitials (name)}};
		on setEmail (email) {
			user.prefs.mailAddress = email;
			weblogData.prefs.authorMailAddress = email;
			weblogData.prefs.managingEditor = email;
			weblogData.prefs.webmaster = email};
		
		local (flFinishSetup = false);
		if defined (adrargs^.setupRadio) { //new user
			postedSection = "setupRadio";
			local (name = adrargs^.name);
			local (organization = adrargs^.organization);
			local (email = adrargs^.email);
			local (password = adrargs^.password);
			local (repeat = adrargs^.repeatPassword);
			if system.environment.isMac { //convert name, organization to Mac text
				name = latinToMac.convert (name);
				organization = latinToMac.convert (organization)};
			setName (name);
			setEmail (email);
			user.prefs.organization = organization;
			bundle { //check that the password is ok, and that it matches the repeat password
				if sizeOf (password) < 4 {
					errorMessage = radio.string.getlocalizedstring ("setupRadio.shortPasswordError");
					flError = true};
				if not flError {
					if password != repeat {
						errorMessage = radio.string.getlocalizedstring ("setupRadio.passwordMismatchError");
						flError = true}}};
			if not flError { //register with the cloud
				try { //trap network errors
					radio.cloud.registerWithServer (password, flNewUser:true); //true, to register a new user
					flConfirmPage = true}
				else { //network or other error
					errorMessage = tryError;
					flError = true}}};
		if defined (adrargs^.reInstall) { //existing user with fresh installation
			postedSection = "reInstall";
			local (usernum = string.trimWhiteSpace (adrargs^.usernum));
			if usernum == "" { //error
				errorMessage = radio.string.getlocalizedstring ("setupRadio.noUsernumError");
				flError = true};
			if not flError { //convert the usernum to a number
				try { //convet usernum to a number
					usernum = number (usernum)}
				else { //supplied usernum is not a number -- error
					errorMessage = radio.string.getlocalizedstring ("setupRadio.invalidUsernumError");
					flError = true}};
			if not flError { //check that the usernum is >= 0
				if usernum < 0 { //error
					errorMessage = radio.string.getlocalizedstring ("setupRadio.tooSmallUsernumError");
					flError = true}};
			if not flError { //ping the server
				local (data = user.radio.prefs.defaultCloud);
				data.flDebug = false;
				try { //ping the server
					radio.cloud.registerWithServer (adrargs^.password, flNewUser:false, usernumForExistingUser:usernum);
					radio.webserver.redirect (radio.data.systemUrls.homePage)}
				else { //network or other error
					errorMessage = tryError;
					flError = true}};
			if flError { //redirect to the re-install section of the page
				radio.webserver.redirect (pta^.uri + "#reInstall")}};
		if defined (adrargs^.forgotUsernum) { //existing user who doesn't remember their usernum and password
			postedSection = "forgotUsernum";
			local (email = adrargs^.email, message);
			try {
				if xmlStorageSystem.mailPasswordToUser (email, @message) {
					local (t); new (tableType, @t);
					t.email = email;
					confirmMessage = radio.string.getLocalizedString ("setupRadio.emailSentTo", @t);
					setEmail (email);
					radio.webserver.redirect (pta^.uri + "#reInstall")}
				else { //error on the server
					errorMessage = message;
					flError = true}}
			else { //network error
				local (t); new (tableType, @t);
				t.email = email;
				t.error = tryError;
				errorMessage = radio.string.getlocalizedstring ("setupRadio.emailPasswordError", @t);
				flError = true};
			if flError { //redirect to the forgotten usernum/password section of the page
				radio.webserver.redirect (pta^.uri + "#getUsernum")}};
		if defined (adrargs^.proxy) { //set proxy settings
			postedSection = "proxy";
			try { //convert port to a number -- if not, it's an error
				adrargs^.port = number (adrargs^.port)}
			else {
				errorMessage = radio.string.getlocalizedstring ("setupRadio.invalidProxyPortError");
				adrargs^.enabled = false;
				flError = true};
			user.webBrowser.proxy.domain = adrargs^.domain;
			user.webBrowser.proxy.username = adrargs^.username;
			user.webBrowser.proxy.password = binary (adrargs^.password);
			user.webBrowser.proxy.enabled = false;
			if not flError {
				user.webBrowser.proxy.port = adrargs^.port};
			if defined (adrargs^.enabled) {
				if adrargs^.enabled {
					user.webBrowser.proxy.enabled = true}}; //PBS 12/31/01: *true*, not false (that was a bug)
			if flError { //redirect to the proxy settings section of the page
				radio.webserver.redirect (pta^.uri + "#proxy")}
			else {
				confirmMessage = radio.string.getlocalizedstring ("setupRadio.proxyInfoSetConfirm");
				radio.webserver.redirect (pta^.uri)}};
		if defined (adrargs^.confirmSetup) { //redirect to the home page
			radio.webserver.redirect (radio.data.systemUrls.homePage)};
		<<bundle //3/2/02 JES: old finishSetup code -- commented out because this now happens in radio.bootstrap
			<<if flFinishSetup //write #upstream.xml
				<<local (adrdriver)
				<<if radio.upstream.findDriver (upstreamDriverName, @adrdriver)
					<<local (folder = user.radio.prefs.upstream.folder)
					<<local (f = folder + radio.data.fileNames.upstreamFileName)
					<<if defined (system.temp.radio.upstreamSpecCache.[f])
						<<delete (@system.temp.radio.upstreamSpecCache.[f])
					<<if defined (user.radio.prefs.upstream.servers.[user.radio.prefs.defaultCloud.server])
						<<delete (@user.radio.prefs.upstream.servers.[user.radio.prefs.defaultCloud.server])
					<<try //trap filesystem errors
						<<adrdriver^.saveUpstreamSpec (f, user.radio.prefs.usernum, user.prefs.name)
						<<bundle //set whenLastUpstreamed for all files in the www folder to now plus one second
							<<1/16/02; 2:44:55 AM by JES
								<<This prevents any files from being upstreamed after instaling. The server already has a placeholder page, and the user should see that page, unless they've posted some changes -- i.e. posted an item to their weblog.
							<<local (f, folder = user.radio.prefs.wwwFolder)
							<<fileloop (f in folder, infinity)
								<<local (adrfile)
								<<if radio.file.getFileAttributes (f, @adrfile)
									<<adrfile^.upstream.whenLastUploaded = date (number (file.modified (f)) + 1)
						<<user.radio.prefs.upstream.enabled = true
					<<else
						<<local (t); new (tableType, @t)
						<<t.error = tryError
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.unknownError", @t)
						<<flError = true
		bundle { //if redirecting, set messages in the temp table, and don't bother to finish rendering
			if defined (pta^.radioResponder.redirectUrl) {
				temp.radio.postedSection = postedSection;
				temp.radio.setupRadio.flError = flError;
				temp.radio.setupRadio.errorMessage = errorMessage;
				temp.radio.setupRadio.message = confirmMessage;
				return ("")}
			else { //no redirect -- make sure messages are cleared
				temp.radio.postedSection = "";
				temp.radio.setupRadio.flError = false;
				temp.radio.setupRadio.errorMessage = "";
				temp.radio.setupRadio.message = ""}}};
	
	if flConfirmPage and (not flError) { //render the confirmation page
		pta^.title = " ";
		local (t); new (tableType, @t);
		t.usernum = user.radio.prefs.usernum;
		t.websiteUrl = radio.weblog.getUrl ();
		add (radio.string.getlocalizedstring ("setupRadio.newUserConfirmMessage", @t));
		bundle { //add the Continue button
			add ("<form method=\"POST\">");
			add ("<input type=\"submit\" name=\"confirmSetup\" value=\"" + radio.string.getlocalizedstring ("setupRadio.continueButton") + "\">");
			add ("</form>")}}
	else { //render the welcome/setup form
		local (name = user.prefs.name, email = user.prefs.mailAddress, organization = user.prefs.organization, usernum = "", password);
		if system.environment.isMac { //convert name, organization to latin text
			name = latinToMac.macToLatin (name);
			organization = latinToMac.macToLatin (organization)};
		if defined (user.radio.prefs.passwords.default) {
			password = string (user.radio.prefs.passwords.default)};
		if defined (user.radio.prefs.usernum) {
			usernum = user.radio.prefs.usernum};
		bundle { //render the new user page
			local (t); new (tabletype, @t);
			bundle { //add personal info to replacement table
				t.username = name;
				t.useremail = email;
				t.userorganization = organization;
				t.usernum = usernum;
				t.userpassword = password};
			bundle { //add proxy settings to replacement table
				with user.webBrowser.proxy {
					t.proxydomain = user.webBrowser.proxy.domain;
					t.proxyusername = user.webBrowser.proxy.username;
					t.proxypassword = string (user.webBrowser.proxy.password);
					t.proxyport = user.webBrowser.proxy.port;
					if user.webBrowser.proxy.enabled {
						t.proxyenabled = "checked"}
					else {
						t.proxyenabled = ""}}};
			bundle { //add error or confirmation messages to replacement table
				t.mailPasswordConfirm = "";
				t.proxyConfirm = "";
				t.setupError = "";
				t.reInstallError = "";
				t.getUsernumError = "";
				t.proxyError = "";
				if defined (temp.radio.postedSection) { //only defined after the first POST
					if defined (temp.radio.setupRadio.flError) { //only defined after the first POST
						if temp.radio.setupRadio.flError {
							case temp.radio.postedSection {
								"setupRadio" {
									t.setupError = "<p><font color=\"red\">" + temp.radio.setupRadio.errorMessage + "</font></p>"};
								"reInstall" {
									t.reInstallError = "<p><font color=\"red\">" + temp.radio.setupRadio.errorMessage + "</font></p>"};
								"forgotUsernum" {
									t.getUsernumError = "<p><font color=\"red\">" + temp.radio.setupRadio.errorMessage + "</font></p>"};
								"proxy" {
									t.proxyError = "<p><font color=\"red\">" + temp.radio.setupRadio.errorMessage + "</font></p>"}}}
						else {
							case temp.radio.postedSection {
								"forgotUsernum" {
									t.mailPasswordConfirm = "<p><font color=\"navy\">" + temp.radio.setupRadio.message + "</font></p>"};
								"proxy" {
									t.proxyConfirm = "<p><font color=\"navy\">" + temp.radio.setupRadio.message + "</font></p>"}}}}}};
			add (radio.string.getlocalizedstring ("setupRadio.main", @t))}};
	
	return (htmltext)}
<<bundle //testing
	<<html.setPageTableAddress (@scratchpad.params)
	<<setupRadio ()
	<<html.deletePageTableAddress ()
<<bundle //old code
	<<local (fldebugging = true) //TURN THIS OFF BEFORE RELEASING
	<<if defined (user.radio.prefs.usernum) //already set up; redirect to home page
		<<radio.webserver.redirect (radio.data.systemUrls.homePage)
		<<return ("")
	<<
	<<local (pta = html.getPageTableAddress ())
	<<if fldebugging //copy the pagetable to scratchpad.params
		<<scratchpad.params = pta^; edit (@scratchpad.params)
	<<pta^.title = radio.string.getLocalizedString ("setupRadio.title")
	<<local (adrblog = radio.weblog.init ())
	<<bundle //kludge the weblog title -- [more comments below]
		<<We know the title is initialized by radio.weblog.init to "'s Radio Weblog", so we fix it here, and then put the user's name in once we have it. [JES]
			<<The thing is that rdio.weblog.init uses user.prefs.name to initialize weblogData.prefs.title, but user.prefs.name is the empty string when Radio is first launched.
		<<if adrblog^.prefs.title == "'s Radio Weblog"
			<<adrblog^.prefs.title = "My Radio Weblog"
			<<radio.webserver.redirect (pta^.path)
			<<return ("")
	<<
	<<local (upstreamDriverName = "xmlStorageSystem")
	<<
	<<local (htmltext, indentlevel = 0)
	<<on add (s)
		<<htmltext = htmltext + string.filledstring ("\t", indentlevel) + s + "\r\n"
	<<
	<<local (flRegisteredUserPage = false, flAlreadySetUp = defined (user.radio.prefs.usernum))
	<<if fldebugging
		<<flAlreadySetUp = false
	<<bundle //set flRegisteredUserPage
		<<if defined (pta^.pathArgs) //anything in the pathArgs means run the registered user page
			<<if string.lower (pta^.pathArgs) == "registereduser"
				<<flRegisteredUserPage = true
	<<
	<<local (errorMessage, flError = false, flConfirmPage)
	<<if pta^.method == "POST" //handle a post
		<<local (adrargs = @pta^.radioResponder.postArgs)
		<<if defined (adrargs^.setupRadio) //the name of the submit button
			<<on getInitials (s)
				<<local (initials = "")
				<<bundle //strip off parentheticals
					<<if s contains "("
						<<s = string.nthField (s, "(", 1)
					<<if s contains "["
						<<s = string.nthField (s, "[", 1)
					<<if s contains "{"
						<<s = string.nthField (s, "{", 1)
				<<s = string.trimWhiteSpace (s)
				<<initials = string.upper (s[1])
				<<local (i, ct = sizeOf (s))
				<<if sizeOf (s) > 1
					<<local (flNextCharIsInitial = false)
					<<for i = 2 to ct
						<<if flNextCharIsInitial
							<<if string.isAlpha (s[i])
								<<initials = initials + string.upper (s[i])
							<<flNextCharIsInitial = false
						<<if not string.isAlpha (s[i])
							<<flNextCharIsInitial = true
				<<return (initials)
			<<on setName (name)
				<<user.prefs.name = name
				<<if adrblog^.prefs.title == "My Radio Weblog" //work around a chicken-and-egg problem
					<<The problem & the solution:
						<<radio.thread.agents.mailToWeblog calls radio.weblog.checkMail, which in turn calls radio.weblog.init.
						<<(There may be other places radio.weblog.init is called before we get here as well.)
						<<This happens before we ever get to the desktop website, so you end up with a weblog whose title is "'s Radio Weblog".
						<<Solution: Set user.prefs.name, delete the title, and let radio.weblog.init re-create it.
					<<delete (@adrblog^.prefs.title)
					<<radio.weblog.init ()
				<<weblogData.prefs.authorName = name
				<<bundle //set user.prefs.initials
					<<user.prefs.initials = getInitials (name)
			<<on setEmail (email)
				<<user.prefs.mailAddress = email
				<<weblogData.prefs.authorMailAddress = email
				<<weblogData.prefs.managingEditor = email
				<<weblogData.prefs.webmaster = email
			<<if flRegisteredUserPage //set usernum & password; get user info from cloud
				<<local (usernum = string.trimWhiteSpace (adrargs^.usernum))
				<<if usernum == "" //error
					<<errorMessage = radio.string.getlocalizedstring ("setupRadio.noUsernumError")
				<<if not flError //convert the usernum to a number
					<<try //convet usernum to a number
						<<usernum = number (usernum)
					<<else //supplied usernum is not a number -- error
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.invalidUsernumError")
						<<flError = true
				<<if not flError //check that the usernum is > 999
					<<if usernum < 1000 //error
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.tooSmallUsernumError")
						<<flError = true
				<<if not flError //ping the server
					<<local (data = user.radio.prefs.defaultCloud)
					<<data.flDebug = false
					<<try //ping the server
						<<local (password = adrargs^.password)
						<<local (clouddata)
						<<if xmlStorageSystem.ping (usernum, password, 0, adrdata: @data, adrclouddata:@clouddata) //0 means online (not offline)
							<<local (name = clouddata.name, email = clouddata.email)
							<<if system.environment.isMac
								<<name = latinToMac.convert (name)
							<<user.radio.prefs.usernum = usernum
							<<user.radio.prefs.passwords.default = binary (password)
							<<setName (name)
							<<setEmail (email)
						<<else //the server returned an error
							<<errorMessage = radio.string.getlocalizedstring ("setupRadio.badLoginError")
							<<flError = true
					<<else //network or other error
						<<local (t); new (tableType, @t)
						<<t.error = tryError
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.networkError", @t)
						<<flError = true
				<<flConfirmPage = true
			<<else //process new user args
				<<local (name = adrargs^.name, organization = "")
				<<if defined (adrargs^.organization)
					<<organization = adrargs^.organization
				<<if system.environment.isMac //convert name, organization to Mac text
					<<name = latinToMac.convert (name)
					<<organization = latinToMac.convert (organization)
				<<local (email = adrargs^.email)
				<<local (password = adrargs^.password)
				<<local (repeat = adrargs^.passwordRepeat)
				<<setName (name)
				<<setEmail (email)
				<<user.prefs.organization = organization
				<<bundle //check that the password is ok, and that it matches the repeat password
					<<if sizeOf (password) < 4
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.shortPasswordError")
						<<flError = true
					<<if not flError
						<<if password != repeat
							<<errorMessage = radio.string.getlocalizedstring ("setupRadio.passwordMismatchError")
							<<flError = true
				<<if not flError //register with the cloud
					<<local (data = user.radio.prefs.defaultCloud)
					<<data.flDebug = false
					<<local (response)
					<<try //trap network errors
						<<local (message)
						<<if xmlStorageSystem.register (email, password, adrargs^.name, adrdata:@data, adrresponse:@response)
							<<flConfirmPage = true
							<<user.radio.prefs.usernum = response.usernum
							<<user.radio.prefs.passwords.default = binary (password)
						<<else
							<<errorMessage = message
							<<flError = true
					<<else //network or other error
						<<local (t); new (tableType, @t)
						<<t.error = tryError
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.networkError", @t)
						<<flError = true
			<<if not flError //write #upstream.xml
				<<bundle //set whenLastUpstreamed for index.txt to 1sec after the file's mod-date -- prevents the 1st upstreaming of the home page
					<<local (f = user.radio.prefs.wwwFolder + "index.txt")
					<<file.setModified (f, clock.now ())
					<<local (adrfile)
					<<if radio.file.getFileAttributes (f, @adrfile)
						<<adrfile^.upstream.whenLastUploaded = date (number (file.modified (f)) + 1)
				<<local (adrdriver)
				<<if radio.upstream.findDriver (upstreamDriverName, @adrdriver)
					<<local (folder = user.radio.prefs.upstream.folder)
					<<local (f = folder + radio.data.fileNames.upstreamFileName)
					<<if defined (system.temp.radio.upstreamSpecCache.[f])
						<<delete (@system.temp.radio.upstreamSpecCache.[f])
					<<if defined (user.radio.prefs.upstream.servers.[user.radio.prefs.defaultCloud.server])
						<<delete (@user.radio.prefs.upstream.servers.[user.radio.prefs.defaultCloud.server])
					<<try //trap filesystem errors
						<<adrdriver^.saveUpstreamSpec (f, user.radio.prefs.usernum, user.prefs.name)
						<<user.radio.prefs.upstream.enabled = true
					<<else
						<<local (t); new (tableType, @t)
						<<t.error = tryError
						<<errorMessage = radio.string.getlocalizedstring ("setupRadio.unknownError", @t)
						<<flError = true
		<<if defined (adrargs^.confirmSetup) //setup is complete -- redirect to the weblog editor page
			<<radio.webserver.redirect (radio.data.systemUrls.weblogEditor)
			<<return ("")
	<<
	<<if flAlreadySetUp //don't run the setup page -- tell the user that Radio is already set up
		<<pta^.title = " "
		<<bundle //add already registered message
			<<local (t); new (tableType, @t)
			<<t.websiteUrl = "http://radio.weblogs.com/" + string.padWithZeros (user.radio.prefs.usernum, 7) + "/"
			<<t.usernum = user.radio.prefs.usernum
			<<add (radio.string.getlocalizedstring ("setupRadio.alreadyRegisteredMessage", @t))
		<<bundle //add the Continue button
			<<add ("<form method=\"POST\">")
			<<add ("<input type=\"submit\" name=\"confirmSetup\" value=\"" + radio.string.getlocalizedstring ("setupRadio.continueButton") + "\">")
			<<add ("</form>")
	<<else //run the setup page
		<<if flConfirmPage and (not flError) //render the confirmation page
			<<pta^.title = " "
			<<if flRegisteredUserPage //registered user confirmation
				<<local (t); new (tableType, @t)
				<<t.websiteUrl = "http://radio.weblogs.com/" + string.padWithZeros (user.radio.prefs.usernum, 7) + "/"
				<<t.name = user.prefs.name
				<<add (radio.string.getlocalizedstring ("setupRadio.registeredUserConfirmMessage", @t))
			<<else //new user confirmation
				<<local (t); new (tableType, @t)
				<<t.usernum = user.radio.prefs.usernum
				<<t.websiteUrl = "http://radio.weblogs.com/" + string.padWithZeros (user.radio.prefs.usernum, 7) + "/"
				<<add (radio.string.getlocalizedstring ("setupRadio.newUserConfirmMessage", @t))
			<<bundle //add the Continue button
				<<add ("<form method=\"POST\">")
				<<add ("<input type=\"submit\" name=\"confirmSetup\" value=\"" + radio.string.getlocalizedstring ("setupRadio.continueButton") + "\">")
				<<add ("</form>")
		<<else //render the welcome/setup form
			<<local (name = user.prefs.name, email = user.prefs.mailAddress, organization = user.prefs.organization, usernum = "", password)
			<<if system.environment.isMac //convert name, organization to latin text
				<<name = latinToMac.macToLatin (name)
				<<organization = latinToMac.macToLatin (organization)
			<<if defined (user.radio.prefs.passwords.default)
				<<password = string (user.radio.prefs.passwords.default)
			<<if defined (user.radio.prefs.usernum)
				<<usernum = user.radio.prefs.usernum
			<<if flRegisteredUserPage
				<<bundle //welcome text
					<<add (radio.string.getlocalizedstring ("setupRadio.usernumExplanation"))
				<<bundle //start the form
					<<add ("<form method=\"POST\">"); indentlevel++
				<<bundle //start the table
					<<add ("<table border=\"0\" cellspacing=\"1\" cellpadding=\"5\">"); indentlevel++
				<<bundle //add the error message, if there is one
					<<if flError
						<<add ("<tr><td colspan=\"2\"><b><font color=\"red\">" + errorMessage + "</font></b></td></tr>")
				<<bundle //add form elements
					<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.yourUsernum"), "usernum", 10, 10, usernum))
					<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.passwordForYourUsernum"), "password", 25, 255, password, "password"))
					<<add ("<tr><td></td><td><input type=\"submit\" name=\"setupRadio\" value=\"" + radio.string.getlocalizedstring ("setupRadio.continueButton") + "\"></td></tr>")
				<<bundle //close out the table and the form
					<<add ("</table>"); indentlevel--
					<<add ("</form>"); indentlevel--
			<<else //render the new user page
				<<bundle //old version
					<<bundle //welcome text
						<<add (radio.string.getlocalizedstring ("setupRadio.welcomeText"))
					<<bundle //start the form
						<<add ("<form method=\"POST\">"); indentlevel++
					<<bundle //start the table
						<<add ("<table border=\"0\" cellspacing=\"1\" cellpadding=\"5\">"); indentlevel++
					<<bundle //add the error message, if there is one
						<<if flError
							<<add ("<tr><td colspan=\"2\"><b><font color=\"red\">" + errorMessage + "</font></b></td></tr>")
					<<bundle //add form elements
						<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.name"), "name", 50, 255, name))
						<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.emailAddress"), "email", 25, 255, email))
						<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.organization"), "organization", 50, 255, organization))
						<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.newSitePassword"), "password", 25, 255, password, "password"))
						<<add (radio.html.prefsElement.textItem (radio.string.getlocalizedstring ("setupRadio.repeatPassword"), "passwordRepeat", 25, 255, password, "password"))
						<<add ("<tr><td></td><td><input type=\"submit\" name=\"setupRadio\" value=\"" + radio.string.getlocalizedstring ("setupRadio.continueButton") + "\"></td></tr>")
					<<bundle //close out the table and the form
						<<add ("</table>"); indentlevel--
						<<add ("</form>"); indentlevel--
				<<local (t)
				<<new (tabletype, @t)
				<<t.username = name
				<<t.useremail = email
				<<t.userorganization = organization
				<<t.userpassword = password
				<<with user.webBrowser.proxy
					<<t.proxydomain = user.webBrowser.proxy.domain
					<<t.proxyusername = user.webBrowser.proxy.username
					<<t.proxypassword = string (user.webBrowser.proxy.password)
					<<t.proxyport = user.webBrowser.proxy.port
					<<if user.webBrowser.proxy.enabled
						<<t.proxyenabled = "checked"
					<<else
						<<t.proxyenabled = ""
				<<add (radio.string.getlocalizedstring ("setupRadio.main", @t))
	<<
	<<return (htmltext)



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.