I've cleaned up the code a lot, and merged it all into one file and no longer piping to prep.pl. The module HTML::SmallTemplate is just a simple little template engine I concocted for myself, but is off topic for this discussion. I also put the loading of the full document in a separate CGI to take a little load off this one. My template has a link to that cgi to go in a popup window.
#!/usr/bin/perl $|++; use strict; use CGI; use Data::Dumper; use File::Find; use Time::HiRes qw(gettimeofday); use URI::Escape; use HTML::SmallTemplate qw(readtemplate); $HTML::SmallTemplate::BaseDir = './templates'; my $username = 'josh'; my $logpath = "/Users/$username/Library/Application Support/Adium 2.0/ +Users/Default/Logs/"; my $query = new CGI; print $query->header; my $keyword = $query->param('keyword'); my $data; my $grepmatch = qr/($logpath(.+?)\.(.+?)\/(.+?)\/.+?\((\d{4})\|(\d{2}) +\|(\d{2})\)\.adiumLog):\((\d\d:\d\d:\d\d)\)\ (.+?):(.+)$/; my @matches; if ($keyword) { $$data{adiumLog}{keyword} = $keyword; $$data{results} = &search; } # load template my $page = HTML::SmallTemplate->new(name => 'adiumLog', template => re +adtemplate('adiumLog'), data => $data); $page->parse; print $page->output; sub search { my %msgs; my $lines; scan($logpath); my (@date,@time,@from,@to,@file,@snip,@id); for ( map $_->[0] => sort { $a->[1] cmp $b->[1] } map [$_,"$$_[4]$$_[5]$$_[6]$$_[7]$$_[3]"] => @matches ) { my ($file,$prot,$me,$user,$y,$m,$d,$t,$from,$msg) = @{ +$_}; my $snip = snippit($file,$keyword); $snip =~ s/$keyword/<span class='msg'>$keyword<\/span> +/g; $snip =~ s/\n/<br>/gsm; my $id = join '',gettimeofday; push @date, "$y-$m-$d"; push @time, $t; push @from, $me eq $from ? $me : $user; push @file, uri_escape($file); push @snip, $snip; push @id, $id; push @to, $me eq $from ? $user : $me; } return { date => [@date], time => [@time], from => [@from], file => [@file], snip => [@snip], id => [@id], to => [@to], }; } sub snippit { my ($file,$keyword,$in,@catch) = @_; open F, $file; my $match = qr/$keyword/; while (<F>) { push @catch,tell F; if ($_ =~ $match) { $in=1; } $in++ if $in; if ($in == 4) { last; } elsif (!$in && $#catch > 2) { shift @catch; } } seek F,$catch[0],0; my $snip; read F,$snip,$catch[$#catch]-$catch[0],0; close F; $snip; } sub scan { my @path = @_; my $regex = qr/$keyword/; find( sub { return unless -T; open my $fh, $File::Find::name; domatch($fh, $File::Find::name,$regex); close $fh; }, @path ); } sub domatch { my $fh = shift; my $name = shift; my $regex = shift; while( <$fh> ) { if ( /$regex/o ) { push @matches, ["$name:$_" =~ /$grepmatch/o] a +nd last; } } }

In reply to Re: Search Adium 2.0 Logs by bageler
in thread Search Adium 2.0 Logs by bageler

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.