on default () { «Changes «5/22/03; 11:35:14 AM by DW «Only record searches in history that have more than zero results. Keeps out the spam. «If there are zero results, say so. «Alternate colors to make it look sexy. Nahhh, changed my mind on this. «If the search string doesn't begin with a double-quote, add double-quotes. local (flusecache = true); on getBlogPost (ymd, searchfor, snippet) { searchfor = string.replaceall (searchfor, "\"", ""); local (year = number (string.nthfield (ymd, "/", 1))); local (month = number (string.nthfield (ymd, "/", 2))); local (day = number (string.nthfield (ymd, "/", 3))); local (adrday = mainresponder.calendar.getDayAddress (@scriptingNewsData.calendar, date.set (day, month, year, 0, 0, 0), false)); «edit (adrday) if defined (adrday^) { local (s); case typeof (adrday^) { outlinetype { s = string (adrday^)}; tabletype { local (adrmsg = mainresponder.news.getmessagetable (adrday^.discussionRoot, adrday^.msgnum)); s = string (adrmsg^.body); s = userLandWidgets.removeDoubleSquareBrackets (s)}}; //9/30/99; 11:37:59 AM by DW local (ix = string.patternmatch (string.lower (searchfor), string.lower (s))); local (ixstart = 1, ixend = sizeof (s)); on whitechar (ch) { return ((ch == "\t") or (ch == "\n") or (ch == "\r"))}; for i = ix downto 1 { if whitechar (s [i]) { ixstart = i; break}}; for i = (ix + 1) to sizeof (s) { if whitechar (s [i]) { ixend = i; break}}; local (excerpt = string.mid (s, ixstart, ixend - ixstart + 1)); return (string.trimwhitespace (excerpt))} else { return (snippet)}}; on getDateString (ymd) { local (year = number (string.nthfield (ymd, "/", 1))); local (month = number (string.nthfield (ymd, "/", 2))); local (day = number (string.nthfield (ymd, "/", 3))); local (d = date.set (day, month, year, 0, 0, 0)); return (month + "/" + day + "/" + string.delete (year, 1, 2))}; on getKey () { local (adrkey, adr, mincount = infinity); for adr in @user.google.keypool { if adr^.ct < mincount { mincount = adr^.ct; adrkey = adr}}; adrkey^.ct++; return (adrkey^.key)}; on addToHistory (searchfor) { semaphore.lock (this, 3600); local (adrhistory = @adrcountertable^.history, adr); if not defined (adrhistory^) { new (tabletype, adrhistory); adrcountertable^.cthistory = 0}; for adr in adrhistory { if adr^ == searchfor { delete (adr); break}}; while sizeof (adrhistory^) >= 100 { delete (@adrhistory^ [1])}; adrhistory^.[string.padwithzeros (adrcountertable^.cthistory++, 8)] = searchfor; local (oldtarget = target.set (adrhistory)); table.sortby ("Name"); target.set (oldtarget); semaphore.unlock (this)}; local (pta = html.getpagetableaddress ()); «scratchpad.params = pta^ pta^.title = "Weblog Search Powered by Google"; local (searchfor = ""); case pta^.method { "GET" { local (getargs); new (tabletype, @getargs); webserver.parseArgs (pta^.searchArgs, @getargs); if defined (getargs.q) { searchfor = getargs.q}}}; if searchfor != "" { //add double-quotes if not present searchfor = string.trimwhitespace (searchfor); if searchfor contains " " { if not (searchfor beginswith "\"") { searchfor = "\"" + searchfor}; if not (searchfor endswith "\"") { searchfor = searchfor + "\""}}}; local (adrcountertable); bundle { //manage today's Google counter local (now = clock.now ()); adrcountertable = @scratchpad.googleCounter; if not defined (adrcountertable^) { new (tabletype, adrcountertable); adrcountertable^.today = now; adrcountertable^.ctcalls = 0; adrcountertable^.ctcallstoday = 0}; if date.day () != date.day (adrcountertable^.today) { //day rollover adrcountertable^.ctcallstoday = 0; adrcountertable^.today = now}; «bundle //manage history sub-table «if searchfor != "" «local (adrhistory = @adrcountertable^.history, adr) «if not defined (adrhistory^) «new (tabletype, adrhistory) «adrcountertable^.cthistory = 0 «for adr in adrhistory «if adr^ == searchfor «delete (adr) «break «while sizeof (adrhistory^) >= 100 «delete (@adrhistory^ [1]) «adrhistory^.[string.padwithzeros (adrcountertable^.cthistory++, 8)] = searchfor «local (oldtarget = target.set (adrhistory)) «table.sortby ("Name") «target.set (oldtarget)}; local (htmltext = "", indentlevel = 0); on add (s) { htmltext = htmltext + string.filledstring ("\t", indentlevel) + s + "\r"}; bundle { //add form add ("
"); indentlevel++; add ("
\"Click
"); add ("
"); indentlevel--}; bundle { //add search results if searchfor != "" { local (adrcache = @system.temp.googleWeblogSearch); «new (tabletype, adrcache) if not defined (adrcache^) { new (tabletype, adrcache)}; adrcache = @adrcache^.[searchfor]; if flusecache and defined (adrcache^) { addToHistory (searchfor); add (string (adrcache^))} else { //not in cache, call the search engine local (results); bundle { //fill results new (tabletype, @results); on addtoresults (googletable, ix) { local (adrelement); for adrelement in @googletable.resultelements { try { local (url = adrelement^.url); if string.lower (url) beginswith "http://scriptingnews.userland.com/" { url = string.delete (url, 1, sizeof ("http://scriptingnews.userland.com/"))}; if string.lower (url) beginswith "backissues/" { url = string.delete (url, 1, sizeof ("backissues/"))}; local (adrsubtable = @results.[url]); new (tabletype, adrsubtable); adrsubtable^.snippet = adrelement^.snippet; adrsubtable^.rank = ix++}}}; local (queryString = searchfor + " site:scriptingnews.userland.com"); local (googleresult = google.search (queryString, 0, key:getkey ())); //start at 0 adrcountertable^.ctcalls++; adrcountertable^.ctcallstoday++; local (ctloops = (googleresult.estimatedTotalResultsCount / 10) - 1, i); if ctloops > 5 { //no more than 50 matches ctloops = 5}; addtoresults (googleresult, 0); for i = 1 to ctloops { addtoresults (google.search (queryString, i * 10, key:getkey ()), i * 10); adrcountertable^.ctcalls++; adrcountertable^.ctcallstoday++}; if sizeof (results) > 0 { addToHistory (searchfor)}; «scratchpad .googleresults = results//; edit (@scratchpad.googleresults) };«results = scratchpad.googleresults //for testing bundle { //generate cache element with html text local (htmltext = "", indentlevel = 0); on add (s) { htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n");}; if sizeof (results) > 0 { local (rowbgcolor = white); add (""); indentlevel++; «add ("") for i = sizeof (results) downto 1 { adr = @results [i]; try { local (ymd = nameof (adr^)); local (y = number (string.nthfield (ymd, "/", 1))); if (y >= 1997) and (y <= date.year ()) { local (url = "http://scriptingnews.userland.com/" + ymd); add (""); «if rowbgcolor == beige «rowbgcolor = whitesmoke «else «rowbgcolor = beige}}}; add ("
DateSnippet
" + getdatestring (ymd) + ":" + getblogpost (ymd, searchfor, adr^.snippet) + "
"); indentlevel--} else { add ("There are no matches for " + searchfor + ".")}; adrcache^ = htmltext}; add (string (adrcache^))}}}; bundle { //add counter add ("

Searches today/all time: " + adrcountertable^.ctcallstoday + "/" + adrcountertable^.ctcalls + ".

"); add ("

Most recent 100 searches.

")}; return (manilasuite.untaint (htmltext))}