PostScript Referral Log Analyzer
By Don Lancaster                                                                   
Version 1.3 February 25, 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 available.
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 and sorted long term summary referral file.

% The routines also show you how to sort on internal array values.

% 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 literal name) and a count...

% 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:

%%%%%%%%% (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       % daily input data
/target refreportfilename (w) file def        % summed output 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 {

{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
             refdict curstr known       % already in dictionary?
             {bumpcount}                % yes, bump the count
             {addref} ifelse            % no, add new entry
             } 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
            } def

% addref inserts a new referral to refdict

/addref {refdict begin                  % open refdict
         curstr 1 store                 % enter ref and count
         end} 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

% 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 0 get target (\() writestring
                target exch writestring               % write lines
                target (\)     ) writestring
                1 get target exch writestring
                target (\n) writestring } forall      % write cr

               target (\n>> def\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



Please click here to...