HTMLGenerator.pm 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. package Pisg::HTMLGenerator;
  2. use strict;
  3. $^W = 1;
  4. my ($conf, $debug, $parser, $stats, $users, %T);
  5. sub new
  6. {
  7. my $self = shift;
  8. $conf = shift;
  9. $debug = shift;
  10. $stats = shift;
  11. $users = shift;
  12. %T = @_;
  13. # Load the Common module from wherever it's configured to be.
  14. push(@INC, $conf->{modules_dir});
  15. require Pisg::Common;
  16. Pisg::Common->import();
  17. return bless {};
  18. }
  19. sub create_html
  20. {
  21. # This is where all subroutines get executed, you can actually design
  22. # your own layout here, the lines should be self-explainable
  23. print "Now generating HTML($conf->{outputfile})...\n";
  24. open (OUTPUT, "> $conf->{outputfile}") or
  25. die("$0: Unable to open outputfile($conf->{outputfile}): $!\n");
  26. if ($conf->{show_time}) {
  27. $conf->{tablewidth} += 40;
  28. }
  29. if ($conf->{show_words}) {
  30. $conf->{tablewidth} += 40;
  31. }
  32. if ($conf->{show_wpl}) {
  33. $conf->{tablewidth} += 40;
  34. }
  35. if ($conf->{show_cpl}) {
  36. $conf->{tablewidth} += 40;
  37. }
  38. $conf->{headwidth} = $conf->{tablewidth} - 4;
  39. htmlheader($stats);
  40. pageheader($stats);
  41. activetimes($stats);
  42. activenicks($stats);
  43. headline(template_text('bignumtopic'));
  44. html("<table width=\"$conf->{tablewidth}\">\n"); # Needed for sections
  45. questions($stats);
  46. shoutpeople($stats);
  47. capspeople($stats);
  48. violent($stats);
  49. mostsmiles($stats);
  50. mostsad($stats);
  51. linelengths($stats);
  52. mostwords($stats);
  53. mostwordsperline($stats);
  54. html("</table>"); # Needed for sections
  55. mostusedword($stats);
  56. mostreferencednicks($stats);
  57. mosturls($stats);
  58. headline(template_text('othernumtopic'));
  59. html("<table width=\"$conf->{tablewidth}\">\n"); # Needed for sections
  60. gotkicks($stats);
  61. mostkicks($stats);
  62. mostop($stats);
  63. mostactions($stats);
  64. mostmonologues($stats);
  65. mostjoins($stats);
  66. mostfoul($stats);
  67. html("</table>"); # Needed for sections
  68. headline(template_text('latesttopic'));
  69. html("<table width=\"$conf->{tablewidth}\">\n"); # Needed for sections
  70. lasttopics($stats);
  71. html("</table>"); # Needed for sections
  72. my %hash = ( lines => $stats->{totallines} );
  73. html(template_text('totallines', %hash) . "<br><br>");
  74. htmlfooter($stats);
  75. close(OUTPUT);
  76. }
  77. # Some HTML subs
  78. sub htmlheader
  79. {
  80. my ($stats) = @_;
  81. my $bgpic = "";
  82. if ($conf->{bgpic}) {
  83. $bgpic = " background=\"$conf->{bgpic}\"";
  84. }
  85. print OUTPUT <<HTML;
  86. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  87. <html>
  88. <head>
  89. <title>$conf->{channel} @ $conf->{network} channel statistics</title>
  90. <style type="text/css">
  91. a { text-decoration: none }
  92. a:link { color: $conf->{link}; }
  93. a:visited { color: $conf->{vlink}; }
  94. a:hover { text-decoration: underline; color: $conf->{hlink} }
  95. body {
  96. background-color: $conf->{bgcolor};
  97. font-family: verdana, arial, sans-serif;
  98. font-size: 13px;
  99. color: $conf->{text};
  100. }
  101. td {
  102. font-family: verdana, arial, sans-serif;
  103. font-size: 13px;
  104. color: $conf->{tdcolor};
  105. }
  106. .title {
  107. font-family: tahoma, arial, sans-serif;
  108. font-size: 16px;
  109. font-weight: bold;
  110. }
  111. .headline { color: $conf->{hcolor}; }
  112. .small { font-family: verdana, arial, sans-serif; font-size: 10px; }
  113. .asmall {
  114. font-family: arial narrow, sans-serif;
  115. font-size: 10px;
  116. color: $conf->{text};
  117. }
  118. </style></head>
  119. <body$bgpic>
  120. <div align="center">
  121. HTML
  122. my %hash = (
  123. network => $conf->{network},
  124. maintainer => $conf->{maintainer},
  125. days => $stats->{days},
  126. nicks => scalar keys %{ $stats->{lines} }
  127. );
  128. print OUTPUT "<span class=\"title\">" . template_text('pagetitle1', %hash) . "</span><br>";
  129. print OUTPUT "<br>";
  130. print OUTPUT template_text('pagetitle2', %hash);
  131. sub timefix
  132. {
  133. my ($timezone, $sec, $min, $hour, $mday, $mon, $year, $wday, $month, $day, $tday, $wdisplay, @month, @day, $timefixx, %hash);
  134. $month = template_text('month', %hash);
  135. $day = template_text('day', %hash);
  136. @month=split / /, $month;
  137. @day=split / /, $day;
  138. # Get the Date from the users computer
  139. $timezone = $conf->{timeoffset} * 3600;
  140. ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time+$timezone);
  141. $year += 1900; # Y2K Patch
  142. $min =~ s/^(.)$/0$1/; # Fixes the display of mins/secs below
  143. $sec =~ s/^(.)$/0$1/; # it displays 03 instead of 3
  144. if($hour > '23') { # Checks to see if it Midnight
  145. $hour = 12; # Makes it display the hour 12
  146. $tday = "AM"; # Display AM
  147. }
  148. elsif($hour > '12') { # Get rid of the Military time and
  149. $hour -= 12; # put it into normal time
  150. $tday = "PM"; # If past Noon and before Midnight set
  151. } # the time as PM
  152. else {
  153. $tday = "AM"; # If it's past Midnight and before Noon
  154. } # set the time as AM
  155. # Use 24 hours pr. day
  156. if($tday eq "PM" && $hour < '12') {
  157. $hour += 12;
  158. }
  159. print OUTPUT "$day[$wday] $mday $month[$mon] $year - $hour:$min:$sec\n";
  160. }
  161. timefix();
  162. print OUTPUT "<br>" . template_text('pagetitle3', %hash) . "<br><br>";
  163. }
  164. sub htmlfooter
  165. {
  166. my ($stats) = @_;
  167. print OUTPUT <<HTML;
  168. <span class="small">
  169. Stats generated by <a href="http://pisg.sourceforge.net/" title="Go to the pisg homepage">pisg</a> $conf->{version}<br>
  170. pisg by <a href="http://www.wtf.dk/hp/" title="Go to the authors homepage">Morten "LostStar" Brix Pedersen</a> and others<br>
  171. Stats generated in $stats->{processtime}
  172. </span>
  173. </div>
  174. </body>
  175. </html>
  176. HTML
  177. }
  178. sub headline
  179. {
  180. my ($title) = @_;
  181. print OUTPUT <<HTML;
  182. <br>
  183. <table width="$conf->{headwidth}" cellpadding="1" cellspacing="0" border="0">
  184. <tr>
  185. <td bgcolor="$conf->{headline}">
  186. <table width="100%" cellpadding="2" cellspacing="0" border="0" align="center">
  187. <tr>
  188. <td bgcolor="$conf->{hbgcolor}" class="text10">
  189. <div align="center" class="headline"><b>$title</b></div>
  190. </td>
  191. </tr>
  192. </table>
  193. </td>
  194. </tr>
  195. </table>
  196. HTML
  197. }
  198. sub pageheader
  199. {
  200. if ($conf->{pagehead} ne 'none') {
  201. open(PAGEHEAD, $conf->{pagehead}) or die("$0: Unable to open $conf->{pagehead} for reading: $!\n");
  202. while (<PAGEHEAD>) {
  203. html($_);
  204. }
  205. }
  206. }
  207. sub activetimes
  208. {
  209. # The most actives times on the channel
  210. my ($stats) = @_;
  211. my (%output, $tbgcolor);
  212. &headline(template_text('activetimestopic'));
  213. my @toptime = sort { $stats->{times}{$b} <=> $stats->{times}{$a} } keys %{ $stats->{times} };
  214. my $highest_value = $stats->{times}{$toptime[0]};
  215. my @now = localtime($conf->{timestamp});
  216. my $image;
  217. for my $hour (sort keys %{ $stats->{times} }) {
  218. $debug->("Time: $hour => ". $stats->{times}{$hour});
  219. my $size = ($stats->{times}{$hour} / $highest_value) * 100;
  220. my $percent = ($stats->{times}{$hour} / $stats->{totallines}) * 100;
  221. $percent =~ s/(\.\d)\d+/$1/;
  222. if ($size < 1 && $size != 0) {
  223. # Opera doesn't understand '0.xxxx' in the height="xx" attr,
  224. # so we simply round up to 1.0 here.
  225. $size = 1.0;
  226. }
  227. if ($conf->{timeoffset} =~ /\+(\d+)/) {
  228. # We must plus some hours to the time
  229. $hour += $1;
  230. $hour = $hour % 24;
  231. if ($hour < 10) { $hour = "0" . $hour; }
  232. } elsif ($conf->{timeoffset} =~ /-(\d+)/) {
  233. # We must remove some hours from the time
  234. $hour -= $1;
  235. $hour = $hour % 24;
  236. if ($hour < 10) { $hour = "0" . $hour; }
  237. }
  238. $image = "pic_v_".(int($hour/6)*6);
  239. $image = $conf->{$image};
  240. $debug->("Image: $image");
  241. $output{$hour} = "<td align=\"center\" valign=\"bottom\" class=\"asmall\">$percent%<br><img src=\"$image\" width=\"15\" height=\"$size\" alt=\"$percent\"></td>\n";
  242. }
  243. html("<table border=\"0\" width=\"$conf->{tablewidth}\"><tr>\n");
  244. for ($b = 0; $b < 24; $b++) {
  245. if ($b < 10) { $a = "0" . $b; } else { $a = $b; }
  246. if (!defined($output{$a}) || $output{$a} eq "") {
  247. html("<td align=\"center\" valign=\"bottom\" class=\"asmall\">0%</td>");
  248. } else {
  249. html($output{$a});
  250. }
  251. }
  252. html("</tr><tr>");
  253. for ($b = 0; $b < 24; $b++) {
  254. if ($now[2] == $b) { $tbgcolor = "\#AAAAAA"; } else { $tbgcolor = "\#CCCCCC"; }
  255. html("<td bgcolor=\"$tbgcolor\" align=\"center\" class=\"small\">$b</td>");
  256. }
  257. html("</tr></table>");
  258. if($conf->{show_legend} == 1) {
  259. &legend();
  260. }
  261. }
  262. sub activenicks
  263. {
  264. # The most active nicks (those who wrote most lines)
  265. my ($stats) = @_;
  266. headline(template_text('activenickstopic'));
  267. html("<table border=\"0\" width=\"$conf->{tablewidth}\"><tr>");
  268. html("<td>&nbsp;</td><td bgcolor=\"$conf->{tdtop}\"><b>"
  269. . template_text('nick') . "</b></td><td bgcolor=\"$conf->{tdtop}\"><b>"
  270. . template_text('numberlines')
  271. . "</b></td><td bgcolor=\"$conf->{tdtop}\"><b>"
  272. . ($conf->{show_time} ? template_text('show_time')."</b></td><td bgcolor=\"$conf->{tdtop}\"><b>" : "")
  273. . ($conf->{show_words} ? template_text('show_words')."</b></td><td bgcolor=\"$conf->{tdtop}\"><b>" : "")
  274. . ($conf->{show_wpl} ? template_text('show_wpl')."</b></td><td bgcolor=\"$conf->{tdtop}\"><b>" : "")
  275. . ($conf->{show_cpl} ? template_text('show_cpl')."</b></td><td bgcolor=\"$conf->{tdtop}\"><b>" : "")
  276. . template_text('randquote') ."</b></td>");
  277. if (scalar keys %{$users->{userpics}} > 0) {
  278. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('userpic') ."</b></td>");
  279. }
  280. html("</tr>");
  281. my @active = sort { $stats->{lines}{$b} <=> $stats->{lines}{$a} } keys %{ $stats->{lines} };
  282. my $nicks = scalar keys %{ $stats->{lines} };
  283. if ($conf->{activenicks} > $nicks) {
  284. $conf->{activenicks} = $nicks;
  285. print "Note: There were fewer nicks in the logfile than your specificied there to be in most active nicks...\n";
  286. }
  287. my ($nick, $visiblenick, $randomline, %hash);
  288. my $i = 1;
  289. for (my $c = 0; $c < $conf->{activenicks}; $c++) {
  290. $nick = $active[$c];
  291. $visiblenick = $active[$c];
  292. if (not defined $stats->{sayings}{$nick}) {
  293. $randomline = "";
  294. } else {
  295. $randomline = htmlentities($stats->{sayings}{$nick});
  296. }
  297. # Convert URLs and e-mail addys to links
  298. $randomline = replace_links($randomline);
  299. # Add a link to the nick if there is any
  300. if ($users->{userlinks}{$nick}) {
  301. $visiblenick = replace_links($users->{userlinks}{$nick}, $nick);
  302. }
  303. my $h = $conf->{hicell};
  304. $h =~ s/^#//;
  305. $h = hex $h;
  306. my $h2 = $conf->{hicell2};
  307. $h2 =~ s/^#//;
  308. $h2 = hex $h2;
  309. my $f_b = $h & 0xff;
  310. my $f_g = ($h & 0xff00) >> 8;
  311. my $f_r = ($h & 0xff0000) >> 16;
  312. my $t_b = $h2 & 0xff;
  313. my $t_g = ($h2 & 0xff00) >> 8;
  314. my $t_r = ($h2 & 0xff0000) >> 16;
  315. my $col_b = sprintf "%0.2x", abs int(((($t_b - $f_b) / $conf->{activenicks}) * +$c) + $f_b);
  316. my $col_g = sprintf "%0.2x", abs int(((($t_g - $f_g) / $conf->{activenicks}) * +$c) + $f_g);
  317. my $col_r = sprintf "%0.2x", abs int(((($t_r - $f_r) / $conf->{activenicks}) * +$c) + $f_r);
  318. html("<tr><td bgcolor=\"$conf->{rankc}\" align=\"left\">");
  319. my $line = $stats->{lines}{$nick};
  320. my $w = $stats->{words}{$nick};
  321. my $ch = $stats->{lengths}{$nick};
  322. html("$i</td><td bgcolor=\"#$col_r$col_g$col_b\">$visiblenick</td>"
  323. . ($conf->{show_linetime} ?
  324. "<td bgcolor=\"$col_r$col_g$col_b\">".user_linetimes($stats,$nick,$active[0])."</td>"
  325. : "<td bgcolor=\"#$col_r$col_g$col_b\">$line</td>")
  326. . ($conf->{show_time} ?
  327. "<td bgcolor=\"$col_r$col_g$col_b\">".user_times($stats,$nick)."</td>"
  328. : "")
  329. . ($conf->{show_words} ?
  330. "<td bgcolor=\"#$col_r$col_g$col_b\">$w</td>"
  331. : "")
  332. . ($conf->{show_wpl} ?
  333. "<td bgcolor=\"#$col_r$col_g$col_b\">".sprintf("%.1f",$w/$line)."</td>"
  334. : "")
  335. . ($conf->{show_cpl} ?
  336. "<td bgcolor=\"#$col_r$col_g$col_b\">".sprintf("%.1f",$ch/$line)."</td>"
  337. : "")
  338. ."<td bgcolor=\"#$col_r$col_g$col_b\">");
  339. html("\"$randomline\"</td>");
  340. if ($users->{userpics}{$nick}) {
  341. html("<td bgcolor=\"#$col_r$col_g$col_b\" align=\"center\"><img valign=\"middle\" src=\"$conf->{imagepath}$users->{userpics}{$nick}\"></td>");
  342. }
  343. html("</tr>");
  344. $i++;
  345. }
  346. html("</table><br>");
  347. # Almost as active nicks ('These didn't make it to the top..')
  348. my $nickstoshow = $conf->{activenicks} + $conf->{activenicks2};
  349. $hash{totalnicks} = $nicks - $nickstoshow;
  350. unless ($nickstoshow > $nicks) {
  351. html("<br><b><i>" . template_text('nottop') . "</i></b><table><tr>");
  352. for (my $c = $conf->{activenicks}; $c < $nickstoshow; $c++) {
  353. unless ($c % 5) { unless ($c == $conf->{activenicks}) { html("</tr><tr>"); } }
  354. html("<td bgcolor=\"$conf->{rankc}\" class=\"small\">");
  355. my $nick = $active[$c];
  356. my $lines = $stats->{lines}{$nick};
  357. html("$nick ($lines)</td>");
  358. }
  359. html("</table>");
  360. }
  361. if($hash{totalnicks} > 0) {
  362. html("<br><b>" . template_text('totalnicks', %hash) . "</b><br>");
  363. }
  364. }
  365. sub html
  366. {
  367. my $html = shift;
  368. print OUTPUT "$html\n";
  369. }
  370. sub questions
  371. {
  372. # Persons who asked the most questions
  373. my ($stats) = @_;
  374. my %qpercent;
  375. foreach my $nick (sort keys %{ $stats->{questions} }) {
  376. if ($stats->{lines}{$nick} > 100) {
  377. $qpercent{$nick} = ($stats->{questions}{$nick} / $stats->{lines}{$nick}) * 100;
  378. $qpercent{$nick} =~ s/(\.\d)\d+/$1/;
  379. }
  380. }
  381. my @question = sort { $qpercent{$b} <=> $qpercent{$a} } keys %qpercent;
  382. if (@question) {
  383. my %hash = (
  384. nick => $question[0],
  385. per => $qpercent{$question[0]}
  386. );
  387. my $text = template_text('question1', %hash);
  388. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  389. if (@question >= 2) {
  390. my %hash = (
  391. nick => $question[1],
  392. per => $qpercent{$question[1]}
  393. );
  394. my $text = template_text('question2', %hash);
  395. html("<br><span class=\"small\">$text</span>");
  396. }
  397. html("</td></tr>");
  398. } else {
  399. html("<tr><td bgcolor=\"$conf->{hicell}\">" . template_text('question3') . "</td></tr>");
  400. }
  401. }
  402. sub shoutpeople
  403. {
  404. # The ones who speak with exclamation points!
  405. my ($stats) = @_;
  406. my %spercent;
  407. foreach my $nick (sort keys %{ $stats->{shouts} }) {
  408. if ($stats->{lines}{$nick} > 100) {
  409. $spercent{$nick} = ($stats->{shouts}{$nick} / $stats->{lines}{$nick}) * 100;
  410. $spercent{$nick} =~ s/(\.\d)\d+/$1/;
  411. }
  412. }
  413. my @shout = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent;
  414. if (@shout) {
  415. my %hash = (
  416. nick => $shout[0],
  417. per => $spercent{$shout[0]}
  418. );
  419. my $text = template_text('shout1', %hash);
  420. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  421. if (@shout >= 2) {
  422. my %hash = (
  423. nick => $shout[1],
  424. per => $spercent{$shout[1]}
  425. );
  426. my $text = template_text('shout2', %hash);
  427. html("<br><span class=\"small\">$text</span>");
  428. }
  429. html("</td></tr>");
  430. } else {
  431. my $text = template_text('shout3');
  432. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  433. }
  434. }
  435. sub capspeople
  436. {
  437. # The ones who speak ALL CAPS.
  438. my ($stats) = @_;
  439. my %cpercent;
  440. foreach my $nick (sort keys %{ $stats->{allcaps} }) {
  441. if ($stats->{lines}{$nick} > 100) {
  442. $cpercent{$nick} = $stats->{allcaps}{$nick} / $stats->{lines}{$nick} * 100;
  443. $cpercent{$nick} =~ s/(\.\d)\d+/$1/;
  444. }
  445. }
  446. my @caps = sort { $cpercent{$b} <=> $cpercent{$a} } keys %cpercent;
  447. if (@caps) {
  448. my %hash = (
  449. nick => $caps[0],
  450. per => $cpercent{$caps[0]},
  451. line => htmlentities($stats->{allcaplines}{$caps[0]})
  452. );
  453. my $text = template_text('allcaps1', %hash);
  454. if($conf->{show_shoutline}) {
  455. my $exttext = template_text('allcapstext', %hash);
  456. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br><span class=\"small\">$exttext</span><br>");
  457. } else {
  458. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  459. }
  460. if (@caps >= 2) {
  461. my %hash = (
  462. nick => $caps[1],
  463. per => $cpercent{$caps[1]}
  464. );
  465. my $text = template_text('allcaps2', %hash);
  466. html("<br><span class=\"small\">$text</span>");
  467. }
  468. html("</td></tr>");
  469. } else {
  470. my $text = template_text('allcaps3');
  471. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  472. }
  473. }
  474. sub violent
  475. {
  476. # They attacked others
  477. my ($stats) = @_;
  478. my @aggressors;
  479. @aggressors = sort { $stats->{violence}{$b} <=> $stats->{violence}{$a} }
  480. keys %{ $stats->{violence} };
  481. if(@aggressors) {
  482. my %hash = (
  483. nick => $aggressors[0],
  484. attacks => $stats->{violence}{$aggressors[0]},
  485. line => htmlentities($stats->{violencelines}{$aggressors[0]})
  486. );
  487. my $text = template_text('violent1', %hash);
  488. if($conf->{show_violentlines}) {
  489. my $exttext = template_text('violenttext', %hash);
  490. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br><span class=\"small\">$exttext</span><br>");
  491. } else {
  492. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  493. }
  494. if (@aggressors >= 2) {
  495. my %hash = (
  496. nick => $aggressors[1],
  497. attacks => $stats->{violence}{$aggressors[1]}
  498. );
  499. my $text = template_text('violent2', %hash);
  500. html("<br><span class=\"small\">$text</span>");
  501. }
  502. html("</td></tr>");
  503. } else {
  504. my $text = template_text('violent3');
  505. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  506. }
  507. # They got attacked
  508. my @victims;
  509. @victims = sort { $stats->{attacked}{$b} <=> $stats->{attacked}{$a} }
  510. keys %{ $stats->{attacked} };
  511. if(@victims) {
  512. my %hash = (
  513. nick => $victims[0],
  514. attacks => $stats->{attacked}{$victims[0]},
  515. line => htmlentities($stats->{attackedlines}{$victims[0]})
  516. );
  517. my $text = template_text('attacked1', %hash);
  518. if($conf->{show_violentlines}) {
  519. my $exttext = template_text('attackedtext', %hash);
  520. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br><span class=\"small\">$exttext</span><br>");
  521. } else {
  522. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  523. }
  524. if (@victims >= 2) {
  525. my %hash = (
  526. nick => $victims[1],
  527. attacks => $stats->{attacked}{$victims[1]}
  528. );
  529. my $text = template_text('attacked2', %hash);
  530. html("<br><span class=\"small\">$text</span>");
  531. }
  532. html("</td></tr>");
  533. }
  534. }
  535. sub gotkicks
  536. {
  537. # The persons who got kicked the most
  538. my ($stats) = @_;
  539. my @gotkick = sort { $stats->{gotkicked}{$b} <=> $stats->{gotkicked}{$a} }
  540. keys %{ $stats->{gotkicked} };
  541. if (@gotkick) {
  542. my %hash = (
  543. nick => $gotkick[0],
  544. kicks => $stats->{gotkicked}{$gotkick[0]},
  545. line => $stats->{kicklines}{$gotkick[0]}
  546. );
  547. my $text = template_text('gotkick1', %hash);
  548. if ($conf->{show_kickline}) {
  549. my $exttext = template_text('kicktext', %hash);
  550. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br><span class=\"small\">$exttext</span><br>");
  551. } else {
  552. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  553. }
  554. if (@gotkick >= 2) {
  555. my %hash = (
  556. nick => $gotkick[1],
  557. kicks => $stats->{gotkicked}{$gotkick[1]}
  558. );
  559. my $text = template_text('gotkick2', %hash);
  560. html("<br><span class=\"small\">$text</span>");
  561. }
  562. html("</td></tr>");
  563. }
  564. }
  565. sub mostjoins
  566. {
  567. my ($stats) = @_;
  568. my @joins = sort { $stats->{joins}{$b} <=> $stats->{joins}{$a} }
  569. keys %{ $stats->{joins} };
  570. if (@joins) {
  571. my %hash = (
  572. nick => $joins[0],
  573. joins => $stats->{joins}{$joins[0]}
  574. );
  575. my $text = template_text('joins', %hash);
  576. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  577. }
  578. }
  579. sub mostwords
  580. {
  581. # The person who got words the most
  582. my ($stats) = @_;
  583. my @words = sort { $stats->{words}{$b} <=> $stats->{words}{$a} }
  584. keys %{ $stats->{words} };
  585. if (@words) {
  586. my %hash = (
  587. nick => $words[0],
  588. words => $stats->{words}{$words[0]}
  589. );
  590. my $text = template_text('words1', %hash);
  591. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  592. if (@words >= 2) {
  593. my %hash = (
  594. oldnick => $words[0],
  595. nick => $words[1],
  596. words => $stats->{words}{$words[1]}
  597. );
  598. my $text = template_text('words2', %hash);
  599. html("<br><span class=\"small\">$text</span>");
  600. }
  601. html("</td></tr>");
  602. } else {
  603. my $text = template_text('kick3');
  604. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  605. }
  606. }
  607. sub mostkicks
  608. {
  609. # The person who got kicked the most
  610. my ($stats) = @_;
  611. my @kicked = sort { $stats->{kicked}{$b} <=> $stats->{kicked}{$a} }
  612. keys %{ $stats->{kicked} };
  613. if (@kicked) {
  614. my %hash = (
  615. nick => $kicked[0],
  616. kicked => $stats->{kicked}{$kicked[0]}
  617. );
  618. my $text = template_text('kick1', %hash);
  619. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  620. if (@kicked >= 2) {
  621. my %hash = (
  622. oldnick => $kicked[0],
  623. nick => $kicked[1],
  624. kicked => $stats->{kicked}{$kicked[1]}
  625. );
  626. my $text = template_text('kick2', %hash);
  627. html("<br><span class=\"small\">$text</span>");
  628. }
  629. html("</td></tr>");
  630. } else {
  631. my $text = template_text('kick3');
  632. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  633. }
  634. }
  635. sub mostmonologues
  636. {
  637. # The person who had the most monologues (speaking to himself)
  638. my ($stats) = @_;
  639. my @monologue = sort { $stats->{monologues}{$b} <=> $stats->{monologues}{$a} } keys %{ $stats->{monologues} };
  640. if (@monologue) {
  641. my %hash = (
  642. nick => $monologue[0],
  643. monos => $stats->{monologues}{$monologue[0]}
  644. );
  645. my $text = template_text('mono1', %hash);
  646. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  647. if (@monologue >= 2) {
  648. my %hash = (
  649. nick => $monologue[1],
  650. monos => $stats->{monologues}{$monologue[1]}
  651. );
  652. my $text = template_text('mono2', %hash);
  653. html("<br><span class=\"small\">$text</span>");
  654. }
  655. html("</td></tr>");
  656. }
  657. }
  658. sub linelengths
  659. {
  660. # The person(s) who wrote the longest lines
  661. my ($stats) = @_;
  662. my %len;
  663. foreach my $nick (sort keys %{ $stats->{lengths} }) {
  664. if ($stats->{lines}{$nick} > 100) {
  665. $len{$nick} = $stats->{lengths}{$nick} / $stats->{lines}{$nick};
  666. $len{$nick} =~ s/(\.\d)\d+/$1/;
  667. }
  668. }
  669. my @len = sort { $len{$b} <=> $len{$a} } keys %len;
  670. my $all_lines;
  671. my $totallength;
  672. foreach my $nick (keys %{ $stats->{lines} }) {
  673. $all_lines += $stats->{lines}{$nick};
  674. $totallength += $stats->{lengths}{$nick};
  675. }
  676. my $totalaverage;
  677. if ($all_lines > 0) {
  678. $totalaverage = $totallength / $all_lines;
  679. $totalaverage =~ s/(\.\d)\d+/$1/;
  680. }
  681. if (@len) {
  682. my %hash = (
  683. nick => $len[0],
  684. letters => $len{$len[0]}
  685. );
  686. my $text = template_text('long1', %hash);
  687. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br>");
  688. if (@len >= 2) {
  689. %hash = (
  690. avg => $totalaverage
  691. );
  692. $text = template_text('long2', %hash);
  693. html("<span class=\"small\">$text</span></td></tr>");
  694. }
  695. }
  696. # The person(s) who wrote the shortest lines
  697. if (@len) {
  698. my %hash = (
  699. nick => $len[$#len],
  700. letters => $len{$len[$#len]}
  701. );
  702. my $text = template_text('short1', %hash);
  703. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br>");
  704. if (@len >= 2) {
  705. %hash = (
  706. nick => $len[$#len - 1],
  707. letters => $len{$len[$#len - 1]}
  708. );
  709. $text = template_text('short2', %hash);
  710. html("<span class=\"small\">$text</span></td></tr>");
  711. }
  712. }
  713. }
  714. sub mostfoul
  715. {
  716. my ($stats) = @_;
  717. my %spercent;
  718. foreach my $nick (sort keys %{ $stats->{foul} }) {
  719. if ($stats->{lines}{$nick} > 15) {
  720. $spercent{$nick} = $stats->{foul}{$nick} / $stats->{lines}{$nick} * 100;
  721. $spercent{$nick} =~ s/(\.\d)\d+/$1/;
  722. }
  723. }
  724. my @foul = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent;
  725. if (@foul) {
  726. my %hash = (
  727. nick => $foul[0],
  728. per => $spercent{$foul[0]}
  729. );
  730. my $text = template_text('foul1', %hash);
  731. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  732. if (@foul >= 2) {
  733. my %hash = (
  734. nick => $foul[1],
  735. per => $spercent{$foul[1]}
  736. );
  737. my $text = template_text('foul2', %hash);
  738. html("<br><span class=\"small\">$text</span>");
  739. }
  740. html("</td></tr>");
  741. } else {
  742. my $text = template_text('foul3');
  743. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  744. }
  745. }
  746. sub mostsad
  747. {
  748. my ($stats) = @_;
  749. my %spercent;
  750. foreach my $nick (sort keys %{ $stats->{frowns} }) {
  751. if ($stats->{lines}{$nick} > 100) {
  752. $spercent{$nick} = $stats->{frowns}{$nick} / $stats->{lines}{$nick} * 100;
  753. $spercent{$nick} =~ s/(\.\d)\d+/$1/;
  754. }
  755. }
  756. my @sadface = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent;
  757. if (@sadface) {
  758. my %hash = (
  759. nick => $sadface[0],
  760. per => $spercent{$sadface[0]}
  761. );
  762. my $text = template_text('sad1', %hash);
  763. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  764. if (@sadface >= 2) {
  765. my %hash = (
  766. nick => $sadface[1],
  767. per => $spercent{$sadface[1]}
  768. );
  769. my $text = template_text('sad2', %hash);
  770. html("<br><span class=\"small\">$text</span>");
  771. }
  772. html("</td></tr>");
  773. } else {
  774. my $text = template_text('sad3');
  775. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  776. }
  777. }
  778. sub mostop
  779. {
  780. my ($stats) = @_;
  781. my @ops = sort { $stats->{gaveops}{$b} <=> $stats->{gaveops}{$a} }
  782. keys %{ $stats->{gaveops} };
  783. my @deops = sort { $stats->{tookops}{$b} <=> $stats->{tookops}{$a} }
  784. keys %{ $stats->{tookops} };
  785. if (@ops) {
  786. my %hash = (
  787. nick => $ops[0],
  788. ops => $stats->{gaveops}{$ops[0]}
  789. );
  790. my $text = template_text('mostop1', %hash);
  791. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  792. if (@ops >= 2) {
  793. my %hash = (
  794. nick => $ops[1],
  795. ops => $stats->{gaveops}{$ops[1]}
  796. );
  797. my $text = template_text('mostop2', %hash);
  798. html("<br><span class=\"small\">$text</span>");
  799. }
  800. html("</td></tr>");
  801. } else {
  802. my $text = template_text('mostop3');
  803. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  804. }
  805. if (@deops) {
  806. my %hash = (
  807. nick => $deops[0],
  808. deops => $stats->{tookops}{$deops[0]}
  809. );
  810. my $text = template_text('mostdeop1', %hash);
  811. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  812. if (@deops >= 2) {
  813. my %hash = (
  814. nick => $deops[1],
  815. deops => $stats->{tookops}{$deops[1]}
  816. );
  817. my $text = template_text('mostdeop2', %hash);
  818. html("<br><span class=\"small\">$text</span>");
  819. }
  820. html("</td></tr>");
  821. } else {
  822. my $text = template_text('mostdeop3');
  823. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  824. }
  825. }
  826. sub mostactions
  827. {
  828. # The person who did the most /me's
  829. my ($stats) = @_;
  830. my @actions = sort { $stats->{actions}{$b} <=> $stats->{actions}{$a} }
  831. keys %{ $stats->{actions} };
  832. if (@actions) {
  833. my %hash = (
  834. nick => $actions[0],
  835. actions => $stats->{actions}{$actions[0]},
  836. line => htmlentities($stats->{actionlines}{$actions[0]})
  837. );
  838. my $text = template_text('action1', %hash);
  839. if($conf->{show_actionline}) {
  840. my $exttext = template_text('actiontext', %hash);
  841. html("<tr><td bgcolor=\"$conf->{hicell}\">$text<br><span class=\"small\">$exttext</span><br>");
  842. } else {
  843. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  844. }
  845. if (@actions >= 2) {
  846. my %hash = (
  847. nick => $actions[1],
  848. actions => $stats->{actions}{$actions[1]}
  849. );
  850. my $text = template_text('action2', %hash);
  851. html("<br><span class=\"small\">$text</span>");
  852. }
  853. html("</td></tr>");
  854. } else {
  855. my $text = template_text('action3');
  856. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  857. }
  858. }
  859. sub mostsmiles
  860. {
  861. # The person(s) who smiled the most :-)
  862. my ($stats) = @_;
  863. my %spercent;
  864. foreach my $nick (sort keys %{ $stats->{smiles} }) {
  865. if ($stats->{lines}{$nick} > 100) {
  866. $spercent{$nick} = $stats->{smiles}{$nick} / $stats->{lines}{$nick} * 100;
  867. $spercent{$nick} =~ s/(\.\d)\d+/$1/;
  868. }
  869. }
  870. my @smiles = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent;
  871. if (@smiles) {
  872. my %hash = (
  873. nick => $smiles[0],
  874. per => $spercent{$smiles[0]}
  875. );
  876. my $text = template_text('smiles1', %hash);
  877. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  878. if (@smiles >= 2) {
  879. my %hash = (
  880. nick => $smiles[1],
  881. per => $spercent{$smiles[1]}
  882. );
  883. my $text = template_text('smiles2', %hash);
  884. html("<br><span class=\"small\">$text</span>");
  885. }
  886. html("</td></tr>");
  887. } else {
  888. my $text = template_text('smiles3');
  889. html("<tr><td bgcolor=\"$conf->{hicell}\">$text</td></tr>");
  890. }
  891. }
  892. sub lasttopics
  893. {
  894. my ($stats) = @_;
  895. if ($stats->{topics}) {
  896. $debug->("Total number of topics: " . scalar @{ $stats->{topics} });
  897. my %hash = (
  898. total => scalar @{ $stats->{topics} }
  899. );
  900. my $ltopic = $#{ $stats->{topics} };
  901. my $tlimit = 0;
  902. $conf->{topichistory} -= 1;
  903. if ($ltopic > $conf->{topichistory}) {
  904. $tlimit = $ltopic - $conf->{topichistory};
  905. }
  906. for (my $i = $ltopic; $i >= $tlimit; $i--) {
  907. my $topic = htmlentities($stats->{topics}[$i]{topic});
  908. $topic = replace_links($stats->{topics}[$i]{topic});
  909. # Strip off the quotes (')
  910. $topic =~ s/^\'(.*)\'$/$1/;
  911. my $nick = $stats->{topics}[$i]{nick};
  912. my $hour = $stats->{topics}[$i]{hour};
  913. my $min = $stats->{topics}[$i]{min};
  914. html("<tr><td bgcolor=\"$conf->{hicell}\"><i>$topic</i></td>");
  915. html("<td bgcolor=\"$conf->{hicell}\">By <b>$nick</b> at <b>$hour:$min</b></td></tr>");
  916. }
  917. html("<tr><td align=\"center\" colspan=\"2\" class=\"asmall\">" . template_text('totaltopic', %hash) . "</td></tr>");
  918. } else {
  919. html("<tr><td bgcolor=\"$conf->{hicell}\">" . template_text('notopic') ."</td></tr>");
  920. }
  921. }
  922. sub template_text
  923. {
  924. # This function is for the homemade template system. It receives a name
  925. # of a template and a hash with the fields in the template to update to
  926. # its corresponding value
  927. my $template = shift;
  928. my %hash = @_;
  929. my $text;
  930. unless ($text = $T{$conf->{lang}}{$template}) {
  931. # Fall back to English if the language template doesn't exist
  932. if ($text = $T{EN}{$template}) {
  933. print "Note: There was no translation in $conf->{lang} for '$template' - falling back to English..\n";
  934. } else {
  935. die("No such template '$template' in language file.\n");
  936. }
  937. }
  938. $hash{channel} = $conf->{channel};
  939. foreach my $key (sort keys %hash) {
  940. $text =~ s/\[:$key\]/$hash{$key}/;
  941. $text =~ s/ü/&uuml;/go;
  942. $text =~ s/ö/&ouml;/go;
  943. $text =~ s/ä/&auml;/go;
  944. $text =~ s/ß/&szlig;/go;
  945. $text =~ s/å/&aring;/go;
  946. $text =~ s/æ/&aelig;/go;
  947. $text =~ s/ø/&oslash;/go;
  948. }
  949. if ($text =~ /\[:.*?:.*?:\]/o) {
  950. $text =~ s/\[:(.*?):(.*?):\]/get_subst($1,$2,\%hash)/geo;
  951. }
  952. return $text;
  953. }
  954. sub mostusedword
  955. {
  956. # Lao the infamous word usage statistics
  957. my ($stats) = @_;
  958. my %usages;
  959. foreach my $word (keys %{ $stats->{wordcounts} }) {
  960. # Skip people's nicks.
  961. next if exists $stats->{lines}{$word};
  962. $usages{$word} = $stats->{wordcounts}{$word};
  963. }
  964. my @popular = sort { $usages{$b} <=> $usages{$a} } keys %usages;
  965. if (@popular) {
  966. &headline(template_text('mostwordstopic'));
  967. html("<table border=\"0\" width=\"$conf->{tablewidth}\"><tr>");
  968. html("<td>&nbsp;</td><td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('word') . "</b></td>");
  969. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('numberuses') . "</b></td>");
  970. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('lastused') . "</b></td>");
  971. my $count = 0;
  972. for(my $i = 0; $count < 10; $i++) {
  973. last unless $i < $#popular;
  974. # Skip nicks. It's far more efficient to do this here than when
  975. # @popular is created.
  976. next if is_ignored($popular[$i]);
  977. next if exists $stats->{lines}{find_alias($popular[$i])};
  978. my $a = $count + 1;
  979. my $popular = htmlentities($popular[$i]);
  980. my $wordcount = $stats->{wordcounts}{$popular[$i]};
  981. my $lastused = htmlentities($stats->{wordnicks}{$popular[$i]});
  982. html("<tr><td bgcolor=\"$conf->{rankc}\"><b>$a</b>");
  983. html("<td bgcolor=\"$conf->{hicell}\">$popular</td>");
  984. html("<td bgcolor=\"$conf->{hicell}\">$wordcount</td>");
  985. html("<td bgcolor=\"$conf->{hicell}\">$lastused</td>");
  986. html("</tr>");
  987. $count++;
  988. }
  989. html("</table>");
  990. }
  991. }
  992. sub mostwordsperline
  993. {
  994. # The person who got words the most
  995. my ($stats) = @_;
  996. my %wpl = ();
  997. my ($numlines,$avg,$numwords);
  998. foreach my $n (keys %{ $stats->{words} }) {
  999. $wpl{$n} = sprintf("%.2f", $stats->{words}{$n}/$stats->{lines}{$n});
  1000. $numlines += $stats->{lines}{$n};
  1001. $numwords += $stats->{words}{$n};
  1002. }
  1003. $avg = sprintf("%.2f", $numwords/$numlines);
  1004. my @wpl = sort { $wpl{$b} <=> $wpl{$a} } keys %wpl;
  1005. if (@wpl) {
  1006. my %hash = (
  1007. nick => $wpl[0],
  1008. wpl => $wpl{$wpl[0]}
  1009. );
  1010. my $text = template_text('wpl1', %hash);
  1011. html("<tr><td bgcolor=\"$conf->{hicell}\">$text");
  1012. %hash = (
  1013. avg => $avg
  1014. );
  1015. $text = template_text('wpl2', %hash);
  1016. html("<br><span class=\"small\">$text</span>");
  1017. html("</td></tr>");
  1018. }
  1019. }
  1020. sub mostreferencednicks
  1021. {
  1022. my ($stats) = @_;
  1023. my (%usages);
  1024. foreach my $word (sort keys %{ $stats->{wordcounts} }) {
  1025. next unless exists $stats->{lines}{$word};
  1026. next if is_ignored($word);
  1027. $usages{$word} = $stats->{wordcounts}{$word};
  1028. }
  1029. my @popular = sort { $usages{$b} <=> $usages{$a} } keys %usages;
  1030. if (@popular) {
  1031. &headline(template_text('referencetopic'));
  1032. html("<table border=\"0\" width=\"$conf->{tablewidth}\"><tr>");
  1033. html("<td>&nbsp;</td><td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('nick') . "</b></td>");
  1034. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('numberuses') . "</b></td>");
  1035. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('lastused') . "</b></td>");
  1036. for(my $i = 0; $i < 5; $i++) {
  1037. last unless $i < $#popular;
  1038. my $a = $i + 1;
  1039. my $popular = $popular[$i];
  1040. my $wordcount = $stats->{wordcounts}{$popular[$i]};
  1041. my $lastused = $stats->{wordnicks}{$popular[$i]};
  1042. html("<tr><td bgcolor=\"$conf->{rankc}\"><b>$a</b>");
  1043. html("<td bgcolor=\"$conf->{hicell}\">$popular</td>");
  1044. html("<td bgcolor=\"$conf->{hicell}\">$wordcount</td>");
  1045. html("<td bgcolor=\"$conf->{hicell}\">$lastused</td>");
  1046. html("</tr>");
  1047. }
  1048. html("</table>");
  1049. }
  1050. }
  1051. sub mosturls
  1052. {
  1053. my ($stats) = @_;
  1054. my @sorturls = sort { $stats->{urlcounts}{$b} <=> $stats->{urlcounts}{$a} }
  1055. keys %{ $stats->{urlcounts} };
  1056. if (@sorturls) {
  1057. &headline(template_text('urlstopic'));
  1058. html("<table border=\"0\" width=\"$conf->{tablewidth}\"><tr>");
  1059. html("<td>&nbsp;</td><td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('url') . "</b></td>");
  1060. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('numberuses') . "</b></td>");
  1061. html("<td bgcolor=\"$conf->{tdtop}\"><b>" . template_text('lastused') . "</b></td>");
  1062. for(my $i = 0; $i < 5; $i++) {
  1063. last unless $i < $#sorturls;
  1064. my $a = $i + 1;
  1065. my $sorturl = $sorturls[$i];
  1066. my $urlcount = $stats->{urlcounts}{$sorturls[$i]};
  1067. my $lastused = $stats->{urlnicks}{$sorturls[$i]};
  1068. if (length($sorturl) > 60) {
  1069. $sorturl = substr($sorturl, 0, 60);
  1070. }
  1071. html("<tr><td bgcolor=\"$conf->{rankc}\"><b>$a</b>");
  1072. html("<td bgcolor=\"$conf->{hicell}\"><a href=\"$sorturls[$i]\">$sorturl</a></td>");
  1073. html("<td bgcolor=\"$conf->{hicell}\">$urlcount</td>");
  1074. html("<td bgcolor=\"$conf->{hicell}\">$lastused</td>");
  1075. html("</tr>");
  1076. }
  1077. html("</table>");
  1078. }
  1079. }
  1080. sub legend
  1081. {
  1082. html("<table align=\"center\" border=\"0\" width=\"520\"><tr>");
  1083. html("<td align=\"center\" class=\"asmall\"><img src=\"$conf->{pic_h_0}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"\"> = 0-5</td>");
  1084. html("<td align=\"center\" class=\"asmall\"><img src=\"$conf->{pic_h_6}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"\"> = 6-11</td>");
  1085. html("<td align=\"center\" class=\"asmall\"><img src=\"$conf->{pic_h_12}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"\"> = 12-17</td>");
  1086. html("<td align=\"center\" class=\"asmall\"><img src=\"$conf->{pic_h_18}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"\"> = 18-23</td>");
  1087. html("</tr></table>\n");
  1088. }
  1089. sub replace_links
  1090. {
  1091. # Sub to replace urls and e-mail addys to links
  1092. my $str = shift;
  1093. my $nick = shift;
  1094. my ($url, $email);
  1095. if ($nick) {
  1096. if ($url = match_url($str)) {
  1097. $str =~ s/(\Q$url\E)/<a href="$1" target="_blank" title="Open in new window: $1">$nick<\/a>/g;
  1098. }
  1099. if ($email = match_email($str)) {
  1100. $str =~ s/(\Q$email\E)/<a href="mailto:$1" title="Mail to $nick">$nick<\/a>/g;
  1101. }
  1102. } else {
  1103. if ($url = match_url($str)) {
  1104. $str =~ s/(\Q$url\E)/<a href="$1" target="_blank" title="Open in new window: $1">$1<\/a>/g;
  1105. }
  1106. if ($email = match_email($str)) {
  1107. $str =~ s/(\Q$email\E)/<a href="mailto:$1" title="Mail to $1">$1<\/a>/g;
  1108. }
  1109. }
  1110. return $str;
  1111. }
  1112. sub user_linetimes
  1113. {
  1114. my $stats = shift;
  1115. my $nick = shift;
  1116. my $top = shift;
  1117. my $bar = "";
  1118. my $len = ($stats->{lines}{$nick} / $stats->{lines}{$top}) * 100;
  1119. my $debuglen = 0;
  1120. for (my $i = 0; $i <= 3; $i++) {
  1121. next if not defined $stats->{line_times}{$nick}[$i];
  1122. my $w = int(($stats->{line_times}{$nick}[$i] / $stats->{lines}{$nick}) * $len);
  1123. $debuglen += $w;
  1124. if ($w) {
  1125. my $pic = 'pic_h_'.(6*$i);
  1126. $bar .= "<img src=\"$conf->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" align=\"middle\" alt=\"\">";
  1127. }
  1128. }
  1129. $debug->("Length='$len', Sum='$debuglen'");
  1130. return "$bar&nbsp;$stats->{lines}{$nick}";
  1131. }
  1132. sub user_times
  1133. {
  1134. my ($stats, $nick) = @_;
  1135. my $bar = "";
  1136. for (my $i = 0; $i <= 3; $i++) {
  1137. next if not defined $stats->{line_times}{$nick}[$i];
  1138. my $w = int(($stats->{line_times}{$nick}[$i] / $stats->{lines}{$nick}) * 40);
  1139. if ($w) {
  1140. my $pic = 'pic_h_'.(6*$i);
  1141. $bar .= "<img src=\"$conf->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" alt=\"\">";
  1142. }
  1143. }
  1144. return $bar;
  1145. }
  1146. 1;