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

system.verbs.builtins.radio.outliner.poll

on poll () {
	<<Changes
		<<8/29/02; 8:26:13 PM by JES
			<<Don't call subscriptionChanged callbacks here. They're called by radio.outliner.boldenBuddy instead.
		<<8/26/02; 10:44:14 PM by JES
			<<Changed user.radio.outliner.prefs.enabled to user.radio.outliner.prefs.flPollingEnabled.
		<<5/20/02; 9:50:42 AM by DW
			<<Coerce seconds between polls to a number, per a suggestion from Simone Bettini.
		<<5/12/02; 5:21:05 PM by DW
			<<If user.radio.outliner.prefs.enabled is false, no polling. People who aren't using the outliner will stop polling. You'll have to set the pref true to keep using it.
			<<If an outline hasn't changed in the last 25 polls, decrease the rate of checking by a factor of 100. As soon as it updates, return to the normal polling rate.
		<<4/26/02; 12:55:21 PM by DW
			<<If there's a 404 error, set the subscription's enabled boolean to false so we don't poll again. This is the remedy for people whose servers are getting pounded. Delete or rename the file and Radio users will stop asking about it.
		<<3/31/02; 6:03:53 PM by JES
			<<If adrsub^.timeReceivedLastNotification is defined, don't poll the outline -- the server will tell us when it's changed.
			<<Call tcp.httpClient with flAcceptOpml:true.
		<<3/25/02; 4:25:11 PM by JES
			<<Call callbacks at user.radio.outliner.callbacks.subscriptionChanged, when a subscribed outline has changed.
		<<3/24/02; 5:53:38 PM by JES
			<<Before boldening a buddy heading, read the xml text from the buddy URL, and store it in a subtable of system.temp.Frontier.openUrlCache, for Frontier.tools.windowTypes.commands.openUrl to use.
		<<3/13/02; 11:52:49 AM by DW
			<<Created. Loop over the subscriptions table, emboldening outlines that changed.
	on getResultCode (httpresult) {
		local (s = string.nthfield (httpresult, "\r", 1));
		s = string.trimwhitespace (string.delete (s, 1, sizeof (string.nthfield (s, " ", 1))));
		return (number (string.nthfield (s, " ", 1)))};
	local (adrdata = radio.outliner.init (), adrsub, flonebuddychanged = false);
	if adrdata^.prefs.flPollingEnabled {
		local (ctsecs = adrdata^.prefs.ctSecsBetweenPolls);
		for adrsub in @adrdata^.subscriptions {
			radio.outliner.initSubscription (adrsub);
			if adrsub^.enabled {
				if not defined (adrsub^.timeReceivedLastNotification) { //the server will let us know when this outline changes
					if number (clock.now () - adrsub^.whenLastPoll) >= adrsub^.ctSecondsBetweenPolls {
						adrsub^.whenLastPoll = clock.now ();
						adrsub^.ctPolls++;
						try {
							local (url = nameof (adrsub^));
							local (sizexmltext);
							bundle { //get sizexmltext
								local (s, resultheaders, flgotsizefastway = false, headers);
								bundle { //set up headers
									new (tabletype, @headers);
									headers.referer = radio.outliner.data.urlReferer};
								local (urllist = string.urlsplit (url));
								<<msg ("Checking " + url + ".")
								s = tcp.httpClient (server:urllist [2], path:urllist [3], flMessages:false, ctFollowRedirects:3, timeOutTicks: 60 * adrdata^.prefs.timeOutSecs, adrHdrTable:@headers, flJustHeaders:true, flAcceptOpml:true);
								
								case getResultCode (s) {
									404 {
										adrsub^.enabled = false;
										scripterror ("")}}; //break out of try
								
								<<msg ("")
								new (tabletype, @resultheaders);
								webserver.util.parseHeaders (s, @resultheaders);
								if defined (resultheaders.["Content-Length"]) {
									try {
										sizexmltext = number (resultheaders.["Content-Length"]);
										flgotsizefastway = true}};
								if not flgotsizefastway {
									local (s = string.httpResultSplit (tcp.httpClient (server:urllist [2], path:urllist [3], flMessages:false, ctFollowRedirects:3, timeOutTicks: 60 * adrdata^.prefs.timeOutSecs, adrHdrTable:@headers, flAcceptOpml:true)));
									sizexmltext = sizeof (s)}};
							bundle { //bolden outline if size changed
								if sizexmltext != adrsub^.ctXmlBytes {
									adrsub^.ctXmlBytes = sizexmltext;
									adrsub^.ctSecondsBetweenPolls = adrdata^.prefs.ctSecsBetweenPolls; //xxx
									adrsub^.ctConsecPollsWithNoChange = 0; //xxx
									bundle { //pre-cache the xmltext
										radio.outliner.preCacheUrl (url)};
									<<bundle //call callbacks
										<<local (adr)
										<<for adr in @adrdata^.callbacks.subscriptionChanged
											<<try
												<<while typeOf (adr^) == addressType
													<<adr = adr^
												<<adr^ (adrsub)
									radio.outliner.boldenBuddy (url);
									flonebuddychanged = true}
								else {
									if ++adrsub^.ctConsecPollsWithNoChange >= 25 { //xxx
										adrsub^.ctSecondsBetweenPolls = ctsecs * 100}}};
							adrsub^.whenLastPoll = clock.now ()}}}}};
		if flonebuddychanged {
			radio.outliner.openBuddies (true)}}}
<<bundle //test code
	<<poll ()



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.