//=-- PPPathBreakout.cpp - Path Breakout Usage Page Plugin... ----------------= // // PLUGIN DESCRIPTION: // This plugin // // PLUGIN AUTHOR: // Chris Lattner, Author of Magicstats (sabre@magic.hurrah.com) // // PLUGIN HOMEPAGE: // http://www.nondot.org/MagicStats/Plugins/PathBreakout/ // // PLUGIN VERSION / COMPATIBILITY: // PathBreakout v1.0 / MagicStats 2.0+ // //=---------------------------------------------------------------------------= // This file is copyright (c) 1997-2000 Chris Lattner and stuff. //=---------------------------------------------------------------------------= #include "PagePlugin.h" #include "SerializeEx.h" #include "Table.h" #include "PPPathBreakout.h" #include "BreakoutRenderer.h" INIT_PLUGIN(PPPathBreakout); PPPathBreakout::PPPathBreakout(int &CE) { Flags = FAutoFilter | FIgnoreErrors; ResetState(); CE = 0; } // The full name consists of all of the data settings that alter the data that // is kept track of and stored. void PPPathBreakout::GetFullName(VarTable &Params, String &fullName, int updateFreq) { String Filt; if (Params["Filter"] != 0) { Filt = Params["Filter"]->GetStringValue(); } else { Filt = DefFilter.ToParamStr(); } fullName = String::IntToStr(updateFreq) + Name + Filt; } void PPPathBreakout::ProcessAccess(AccessFormatPlugin &A) { int URLMeat = 0; String URL = A.GetURL(); TotalHits++; TotalBW += A.GetLength(); while (URL[URL.Length()-1] == '/' && URL.Length() > 1) URL.Left(URL.Length()-1); // Strip off trailing /'s if (!URL.nCompare("http://", 7)) URLMeat = 7; // Keep track of Total hits and bandwidth while (URL.Length() > URLMeat) { HitBWRec &R = CountTable[URL]; R.P++; R.S += A.GetLength(); int Idx = URL.strrchr('/'); URL.Left(Idx > 0 ? Idx : 0); } } void PPPathBreakout::ResetState() { CountTable.Clear(); // Free all of the data in the linked list... CountTable.SetDefault(HitBWRec(0, 0)); TotalBW = TotalHits = 0; } void PPPathBreakout::OutputHTML(ostream &O, VarTable &Params) { BreakoutRenderer Renderer(O, Params, Descriptor); int CutOff = 3, Percent = 1; // Default to 3% if (Params.InTable("CutoffValue")) { String Val = Params["CutoffValue"]->GetStringValue(); if (Val.Length() > 0) { CutOff = Val.atoi(); if (Val[Val.Length()-1] != '%') // Not Percentage? Percent = 0; } } // Set up the Caption Field... LinkedList Caption; Caption.AddToTail(String("URL (Top ") + String::IntToStr(CutOff) + (Percent ? "%):" : " hits):")); Caption.AddToTail("Percent:"); Caption.AddToTail("Hits:"); Caption.AddToTail("B/W:"); if (Percent) // When converting to percentage, ROUND UP. CutOff *= (TotalHits+99) / 100; // Copy the data from the table into the linked list... LinkedList List; CountTable.ConvertToList(List); List.Sort(); // Sort the data by URL. // Only output top 3%... LinkedList::Iterator I = List.GetIterator(); while (I) { if (I->S.P < CutOff) I.Remove(); // Advances pointer... else I++; } BreakoutRenderer::Tree TheTree; // LinkedList of TreeRows I = List.GetIterator(); while (I) { LinkedList Fields; String &URL = I->P; int SlashIdx = URL.strrchr('/'); String TopDir = URL; TopDir.Right(TopDir.Length()-SlashIdx-1); if (URL.Length() == 1) TopDir = URL; int Depth = BreakoutRenderer::CalculateURLDepth(URL); Fields.AddToTail(String("" + TopDir + ""); Fields.AddToTail(String::DoubleToStr(1000*I->S.P/TotalHits/10.0,1)+"%"); Fields.AddToTail(String::IntToStr(I->S.P)); Fields.AddToTail(String::IntToStr(I->S.S)); TheTree.AddToTail(DataPair >(Depth, Fields)); I++; } LinkedList ColumnSettings; ColumnSettings.AddToTail(""); ColumnSettings.AddToTail("align=right"); ColumnSettings.AddToTail("align=right"); ColumnSettings.AddToTail("align=right"); Renderer.OutputBreakout(Caption, TheTree, ColumnSettings); } void PPPathBreakout::LoadState(Serialize &I) { unsigned int Version = 0; String Page; ResetState(); I >> Version; // Check version number... switch (Version) { case 100: // Version 1.00 I >> TotalHits >> TotalBW; I >> CountTable; break; default: cout << "Serialized " << Name << " Page plugin is of a version that cannot " << "be deserialized\nwith this version of the plugin. Reseting state.\n"; break; } } void PPPathBreakout::SaveState(Serialize &O) { O << GetCurrentVersion(); // Serialize the Version number O << TotalHits << TotalBW; O << CountTable; }