%! % PostScript Referral Log Summary Analyzer % ========================================== % by Don Lancaster v1.3 February 28, 1998 Version 1.1 January 15, 1998 % Copyright c. 1998 by Don Lancaster and Synergetics, Box 809, % Thatcher AZ, 85552 (520) 428-4073. synergetics@tinaja.com % All commercial rights and all electronic media rights are % *fully* reserved. Linking welcome. Reposting is expressly forbidden. % Consulting services avaialable % Further support on www.tinaja.com/info01.html % (The following is believed correct. Please report any errors or differing experiences.) % This is yet another example of PostScript-as-language applied % to solving real world problems. This particular routine reads % a daily referral log listing and combines the result into a % running long term summary referral file. % Compared to the results from WebTrends or a similar commercial % package, you get an ENTIRE list of only the filtered actual % referrals (minus the blanks, your own site refs, search engines, % and newsgroups), and a count arranged to include different % referrals from related sites, plus full web adddresses. % This utility builds on the results from % http://www.tinaja.com/psutils/reflog1.ps % An input file named refer.log is read the contains the daily log % referrals in a format of a filtered list of referral strings. % An input file named refdict.ps is read that contains a % PostScript dictionary holding key-value pairs consisting of a % string (instead of a name) and a count % %! % % /refdict << % (firstlogref) firstlogrefcount % (secondlogref) secondlogrefcount % (thirdlogref) thirdlogrefcount % .... .... % (nthlogref) nthlogrefcount % >> def % The new referrals are read a line at a time and then either % bump the count of an existing entry or create a new one. % A new referral log is then saved as a renamable refdictx.ps % The GENERAL PROCEDURE for using PostScript-as-language is as % follows: % % (1) Carefully READ the entire file inside your favorite % WP or Editor as an ASCII textfile. % % (2) Carefully MODIFY the filenames and variables and such % so they apply to you. % % (3) SAVE the modified code AS A STANDARD ASCII TEXTFILE using % a unique filename. % % (4) RUN the modified code by dragging and dropping it into % Acrobat Distiller. GhostScript may alternately be used. % % (5) TEST, INTERPRET, and MODIFY your results. % %%%%%%%%% (A) INSTALL AND RUN GONZO UTILITIES %%%%%%%%%%%%%%%%%% % This optionally uses my gonzo utilities from http://www.tinaja.com/psutils/gonzo20.ps % (C:\\windows\\desktop\\gonzo\\gonzo.ps) run % run the gonzo utilities % gonzo begin % activate the gonzo utilities % ps.util.1 begin % % printerror % nuisance begin %%%%%% (B) SUMMARIZE AND TOTALIZE LOG REFERRALS %%%%%%%% /reflogfilename (C:\\windows\\desktop\\Zeketo~1\\refer.log) def /refsumdictfilename (C:\\windows\\desktop\\Zeketo~1\\refdict.ps) def /refreportfilename (C:\\windows\\desktop\\Zeketo~1\\refdictx.ps) def /sourcefile reflogfilename (r) file def % create update file /target refreportfilename (w) file def % for updated data % run refdict to fully enter old refdict dictionary data... refsumdictfilename run % read daily referral log one line at a time... /str 1000 string def % workstring /readdailylog { /newcount 0 def % reset new counter /totalcount 0 def % reset total counter /returncount 0 def % reset return counter /visitcount 0 def % reset visitor counter {sourcefile str readline % read ref log one line {dup length 3 gt {enternewref}if } % at a time and process {dup length 3 gt {enternewref}if exit} % if not a newline ifelse} loop sortdict % sort the ref dictionary writenewdict % and write a new one } def % enternewref finds out if their is a previous referral. % If so, the previous count is bumped. If not, the referral is % entered along with a count of one. /enternewref {/curstr exch store % save current ref croppast# % eliminate mid-page refs fix~ % replace %7E with ~ refdict curstr known % already in dictionary? {bumpcount} % yes, bump the count {addref} ifelse % no, add new entry } def % croppast# eliminates anything in curstr beyond #, eliminating % multiple mid-page references. /croppast# { curstr (#) search % look for # {exch pop exch pop}if % drop match and post /curstr exch store } def % fix~ replaces any %7E values with ~ for url consistency... /fix~ {curstr (%7E) search % look for %7E {exch pop exch (~) exch mergestr % substitute ` mergestr}if % and merge /curstr exch store % and resave } def % bumpcount adds one count to existing dict entry /bumpcount {refdict dup curstr get % get value 1 add % bump by one curstr exch put % and close /returncount returncount 1 % keep score add store } def % addref inserts a new referral to refdict /addref {refdict begin % open refdict curstr 1 store % enter ref and count end /newcount newcount 1 add % keep score store curstr print % save new to log file (\n) print flush } def % and close % /sortdict makes a sortable array out of refdict, whose entries % are normally in a wierdly hashed order... /sortdict { mark refdict {10 string cvs % change number to string exch 100 string cvs exch % change name to string mark 3 1 roll ] % change to [(-)(-)] } forall ] % complete array bubblesorton0 % return sorted array } def % mergestr merges the two top stack strings into one top stack string /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def % THE BUBBLESORT UTILITIES: % ========================= % bubblesort accepts an array of up to 5000 elements on the stack top % and does a classic bubble sort, replacing it with a similar array % whose LARGEST value is first and SMALLEST value is last. /bubblesort {mark exch aload pop counttomark /idx exch def { 0 1 idx 1 sub {pop 2 copy lt {exch} if idx 1 roll} for idx 1 roll /idx idx 1 sub def idx 0 eq {exit} if} loop ] } def % bubblesorton0 accepts an array of arrays and sorts on the zeroth % string element or the first string-to-numeric in each array.... /bubblesorton0 {mark exch aload pop counttomark /idx exch def { 0 1 idx 1 sub {pop 2 copy sortindex get % read array value sortindex 1 eq {cvi} if % change to numeric if count exch sortindex get sortindex 1 eq {cvi} if % change to numeric if count exch % pull array values lt {exch} if idx 1 roll} for idx 1 roll /idx idx 1 sub def idx 0 eq {exit} if} loop ] } def % You now have a choice of sorting by hits (sortindex = 1) % or sorting alphabetically (sortindex = 0). An alphabetical % grouping collects all hits from all pages of a site together, % but a numeric sort is a better choice for further editing. /sortindex 1 def % sort on 0 = alpha 1 = hits % writenewdict creates a new sorted data dictionary, reading a % sorted array of form [(name)(count) (name)(count) ... ] /writenewdict { target (%!\n\n/refdict <<\n\n) writestring { dup 1 get cvi /visitcount exch % count visitors visitcount add store dup 0 get target (\() writestring target exch writestring % write lines target (\) ) writestring 1 get target exch writestring target (\n) writestring % write cr /totalcount totalcount 1 add % keep score store } forall % for each target (\n>> def\n\n) writestring target (% There are now ) writestring target visitcount 10 string cvs writestring target ( total visitors.\n) writestring target (% There are now ) writestring target totalcount 10 string cvs writestring target ( total referral files.\n) writestring target (% There are now ) writestring target returncount 10 string cvs writestring target ( new repeat clickthroughs.\n) writestring target (% There are now ) writestring target newcount 10 string cvs writestring target ( new referral files.\n\n) writestring } def % This does it all readdailylog % summarize referral log %%%%%%%%%%%%%%%%%%% TYPICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% % The refdictx output file should look something like this % when numerically sorted... %% %! %% %% /refdict << %% (http://www.maniac.com/~mbvdt/wumplinks.html) 161 %% (http://www.eskine.com/~johnv/amateur/eletrn.html) 41 %% (http://home.iowa.ss.com/georgescott/links.htm) 31 %% ... %% (http://www.bwana.com/~clyde/greatsites/) 1 %% >> def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright c. 1998 by Don Lancaster and Synergetics, Box 809, % Thatcher AZ, 85552 (520) 428-4073. synergetics@tinaja.com % All commercial rights and all electronic media rights are % *fully* reserved. Linking welcome. Reposting is expressly forbidden. % Consulting services avaialable % Further support on www.tinaja.com/info01.html %EOF