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

on getFileUrl (f) {
		<<1/30/02; 12:15:39 AM by JES
			<<Generalized the support for FTP-type upstream specs, so that any upstream spec which specifies a <url> can be used to calculate the upstream URL, even if no files have been upstreamed yet.
		<<11/12/01; 7:00:04 PM by JES
			<<Added support for ftp drivers. If there's no cached url for the file, but there is one for the folder that contains the upstream spec, calculate the url based on the folder's url.
		<<10/8/01; 7:13:12 PM by JES
			<<Created. Gets the url for a file or folder, based on the value of yourUpstreamFolderUrl, as returned by a xmlStorageSystem.getServerCapabilities call.
			<<If the file already has a file table at, which contains an upstream URL, we return that URL as a shortcut.
			<<The file or folder doesn't have to already exist on disk -- This script will return a valid URL, regardless.
			<<The folder containing the file or folder must already exist.
			<<If the URL can't be determined, for example if there's no upstream spec that applies to the file, then the return value is the empty string.
	local (url = "");
	if file.exists (f) { //try to return the cached URL
		local (adrfile);
		if radio.file.getFileAttributes (f, @adrfile) {
			if adrfile^.upstream.url != "" {
				url = adrfile^.upstream.url}}};
	if url == "" { //calculate the url, based on the server capabilities, upstream spec, or parent folder url
		local (pc = file.getPathChar ());
		local (nomad = f);
		if not (nomad endsWith pc) {
			nomad = string.popSuffix (nomad, pc) + pc};
		if not (file.exists (nomad)) {
			nomad = string.popSuffix (nomad, pc) + pc};
		while not (file.exists (nomad + {
			nomad = file.folderFromPath (nomad);
			if string.countFields (nomad, pc) <= 1 { //reality check
		bundle { //try to calculate the URL pased the upstream spec's folder's URL
			local (adrfolder);
			if radio.file.getFileAttributes (nomad, @adrfolder) {
				if adrfolder^.upstream.url != "" {
					local (remainingpath = string.delete (f, 1, sizeOf (nomad)));
					url = adrfolder^.upstream.url + string.replaceAll (remainingPath, pc, "/")}}};
		if url == "" { //try to get the url from server capabilities for xss, or from the spec, for ftp
			local (upstreamSpecPath = nomad +;
			if file.exists (upstreamSpecPath) {
				local (adrfile, adrspec);
				if radio.file.getFileAttributes (upstreamSpecPath, @adrfile) {
					if radio.upstream.getUpstreamSpec (adrfile, @adrspec) {
						case string.lower (adrspec^.type) {
							"xmlstoragesystem" {
								local (adrcapabilities =[adrspec^.server]);
								if not defined (adrcapabilities^) {
									radio.upstream.getServerCapabilities (adrspec)};
								myUrl = adrcapabilities^.serverCapabilities.yourUpstreamFolderUrl;
								local (relativePath = string.delete (f, 1, sizeOf (file.folderFromPath (upstreamSpecPath))));
								relativePath = string.replaceAll (relativePath, pc, "/");
								url = myUrl + relativePath}}
						else { //the URL can be calculated for any file whose upstream specs specify a <url>
							if defined (adrspec^.url) {
								local (remainingpath = string.delete (f, 1, sizeOf (nomad)));
								url = adrspec^.url + string.replaceAll (remainingPath, pc, "/")}}}}}}};
	return (url)}
<<bundle //test code
	<<dialog.notify (getFileUrl ("Backup:Radio UserLand:www:"))
	<<dialog.notify (getFileUrl ("Backup:Radio UserLand:www:test_www:images:bottomBg.gif"))
	<<dialog.notify (getFileUrl ("Backup:Radio UserLand:www:categories:quotations:images:"))
	<<dialog.notify (getFileUrl ("Backup:Radio UserLand:www:categories:quotations:images:foo.gif"))

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.