Changed stylesheets to use relative scaling for horizontal bars.
[onis.git] / onis
diff --git a/onis b/onis
index 7d794b0..2007435 100755 (executable)
--- a/onis
+++ b/onis
@@ -1,12 +1,12 @@
 #!/usr/bin/perl
 ##########################################################################
-#    onis 0.7.2                                               2005-01-21 #
+#    onis 0.8.0                                               2005-04-17 #
 #---=============--------------------------------------------------------#
 # Language: Perl                                                         #
 # Purpose:  Generating statistics                                        #
 # Input:    IRC-Logfiles                                                 #
 # Output:   One HTML file                                                #
-# Version:  0.7.2 (unstable)                                             #
+# Version:  0.8.0 (unstable)                                             #
 # License:  GPL                                                          #
 # Homepage: http://verplant.org/onis/                                    #
 # Authors:  Florian octo Forster <octo@verplant.org>                     #
@@ -32,12 +32,30 @@ BEGIN
 
 use strict;
 use warnings;
+use vars qw/$VERSION $REVISION/;
 
 use Onis::Config qw/get_config parse_argv read_config/;
 use File::Basename qw/dirname/;
 use Fcntl qw/:flock/;
 
-use vars qw/$VERSION $REVISION/;
+=head1 NAME
+
+onis - onis not irs stats
+
+=head1 SYNOPSIS
+
+B<onis> [I<options>] I<logfile>...
+
+=head1 DESCRIPTION
+
+onis is a script that converts IRC logfiles into an HTML statistics page. It
+provides information about daily channel usage, user activity, and channel
+trivia. It provides a configurable customization and supports Dancer,
+dircproxy, eggdrop, irssi, mIRC, and XChat logs. Persistent data (history
+files) and automatic log purging make onis applicable for a large number of
+logfiles. It also features a powerful translation infrastructure.
+
+=cut
 
 $VERSION = '';
 $REVISION = '$LastChangedRevision$';
@@ -48,13 +66,13 @@ if (!$VERSION)
        $VERSION =~ s/^\D*(\d+).*/r$1/;
 }
 
-our $FILEINFO;
-our $PURGE_LOGS = 0;
+our $FileInfo;
+our $PurgeLogs = 0;
 
 print STDERR $/, __FILE__, ': $Id$' if ($::DEBUG);
 
 parse_argv (@ARGV);
-read_config (get_config ('config') ? get_config ('config') : 'config');
+read_config (get_config ('config') ? get_config ('config') : 'onis.conf');
 read_config (scalar get_config ('theme')) if (get_config ('theme'));
 
 my $output = get_config ('output');
@@ -84,7 +102,7 @@ Options:
                                See 'config' for a complete list.
        --user <name>           Define's the generator's name.
 
-For a full list of all options please read the ``config'' file.
+For a full list of all options please read the onis(1) manpage.
 EOF
        exit (1);
 }
@@ -126,23 +144,23 @@ if (get_config ('logtype'))
 require "Onis/Parser/$logtype.pm";
 require Onis::Parser::Persistent;
 require Onis::Data::Persistent;
-import Onis::Parser qw/parse last_date/;
-import Onis::Parser::Persistent qw#newfile#;
-import Onis::Data::Persistent qw#init#;
+import Onis::Parser (qw(parse last_date));
+import Onis::Parser::Persistent (qw(newfile));
+import Onis::Data::Persistent ();
 
-$FILEINFO = init ('$FILEINFO', 'hash');
+$FileInfo = Onis::Data::Persistent->new ('FileInfo', 'inode', qw(mtime));
 
 if (get_config ('purge_logs'))
 {
        my $temp = lc (get_config ('purge_logs'));
        if (($temp eq 'truncate') or ($temp eq 'shorten'))
        {
-               $PURGE_LOGS = 1;
+               $PurgeLogs = 1;
        }
        elsif (($temp eq 'delete') or ($temp eq 'remove')
                        or ($temp eq 'del'))
        {
-               $PURGE_LOGS = 2;
+               $PurgeLogs = 2;
        }
 }
 
@@ -167,15 +185,18 @@ for (get_config ('input'))
        }
        else
        {
+               my ($old_mtime) = $FileInfo->get ($inode);
+
                print STDERR $/, __FILE__, ": ``$file'': " if ($::DEBUG & 0x200);
-               if (defined ($FILEINFO->{$inode}{'mtime'}))
+
+               if (defined ($old_mtime))
                {
-                       if ($FILEINFO->{$inode}{'mtime'} == $mtime)
+                       if ($old_mtime == $mtime)
                        {
                                print STDERR "File did not change. Skipping." if ($::DEBUG & 0x200);
                                next;
                        }
-                       elsif ($FILEINFO->{$inode}{'mtime'} < $mtime)
+                       elsif ($old_mtime < $mtime)
                        {
                                print STDERR "File changed. Reading it again." if ($::DEBUG & 0x200);
                        }
@@ -188,11 +209,11 @@ for (get_config ('input'))
                {
                        print STDERR "File appears to be new. Reading it." if ($::DEBUG & 0x200);
                }
-               $FILEINFO->{$inode}{'mtime'} = $mtime;
+               $FileInfo->put ($inode, $mtime);
        }
        
        # truncate
-       if ($PURGE_LOGS == 1)
+       if ($PurgeLogs == 1)
        {
                unless (open ($logfile, '+< ' . $file))
                {
@@ -209,7 +230,7 @@ for (get_config ('input'))
                }
        }
        
-       if ($PURGE_LOGS)
+       if ($PurgeLogs)
        {
                unless (flock ($logfile, LOCK_EX))
                {
@@ -228,7 +249,7 @@ for (get_config ('input'))
                }
        }
        
-       newfile ($FILEINFO->{$inode});
+       newfile ($FileInfo->{$inode});
        while (<$logfile>)
        {
                s/\n|\r//g;
@@ -261,11 +282,11 @@ for (get_config ('input'))
                }
        }
 
-       if ($PURGE_LOGS and (($status == 1)
+       if ($PurgeLogs and (($status == 1)
                                or ($status == 2)
                                or ($status == 3)))
        {
-               if (($PURGE_LOGS > 1)
+               if (($PurgeLogs > 1)
                        #and (($position + 1) >= $size)
                        )
                {
@@ -279,7 +300,7 @@ for (get_config ('input'))
                                {
                                        print STDERR $/, __FILE__, ": Unable to delete empty file ``$file'': $!";
                                }
-                               delete ($FILEINFO->{$inode});
+                               delete ($FileInfo->{$inode});
                        }
                        else
                        {
@@ -338,3 +359,217 @@ END
 {
        print $/ if ($::DEBUG);
 }
+
+=head1 OPTIONS
+
+=head2 Core options
+
+=over 4
+
+=item B<config>: I<file>;
+
+Load the config from this file. B<(command line only)>
+
+=item B<users_config>: I<file>;
+
+Sets the file from which to read the user configuration.
+
+=item B<language_file>: I<file>;
+
+Sets the language file/translation to use.
+
+=item B<plugin>: I<string>;
+
+Sets the plugins to load. The plugin B<Core> will always be loaded.
+
+=item B<input>: I<file>;
+
+Read and parse this file(s). B<(config file only)>
+
+=item B<logtype>: I<string>;
+
+Sets the parser to use for parsing the input file.
+
+=item B<output>: I<file>;
+
+Write the generated output to this file.
+
+=item B<overwrite>: I<bool>;
+
+Sets wether or not to overwrite the output-file if it exists.
+
+=item B<purge_logs>: "I<false>" | "I<truncate>" | "I<delete>";
+
+Sets wether logs should be truncated or even removes after they have been
+parsed.
+
+=item B<user>: I<string>;
+
+Sets the user that created the page. Defaults to the environment variable
+B<USER> or "onis", if it is not set.
+
+=item B<channel>: I<string>;
+
+Sets the name of the channel being parsed. Normally this is auto-detected.
+
+=item B<unsharp>: "I<none>" | "I<light>" | "I<medium>" | "I<hard>";
+
+Sets how to do unsharping. What each setting actually does is described in the
+readme and in L<Onis::Data::Core>.
+
+=back
+
+=head2 Appearance
+
+=over 4
+
+=item B<theme>: I<file>;
+
+Theme file to load.
+
+=item B<stylesheet>: I<file>;
+
+Sets the stylesheet to use. This is included in the HTML-file as-is, so you
+have to take care of absolute/relative paths yourself..
+
+=item B<color_codes>: I<bool>;
+
+Wether or not to print the color codes (introduced by mIRC, used by idiots and
+ignored by the rest) in the generated HTML-file. Of course this defaults to not
+print the codes..
+
+=item B<display_images>: I<bool>;
+
+Sets if user-images should be displayed.
+
+=item B<default_image>: I<file>;
+
+Sets the default image to use if no user-defined image is available.
+
+=item B<display_lines>: "I<none>" | "I<number>" | "I<bar>" | "I<both>";
+
+=item B<display_words>: "I<none>" | "I<number>" | "I<bar>" | "I<both>";
+
+=item B<display_chars>: "I<none>" | "I<number>" | "I<bar>" | "I<both>";
+
+Sets if and how lines, words and/or characters should be displayed.
+
+=item B<sort_by>: "I<lines>" | "I<words>" | "I<chars>";
+
+Sets wether to sort by lines, words or characters written.
+
+=item B<display_times>: I<bool>;
+
+Wether or not to display a fixed width bar that shows when a user is most
+active.
+
+=item B<bar_height>: I<number>;
+
+=item B<bar_width>: I<number>;
+
+Sets the width of horizontal bars and the height of vertical bars.
+
+=item B<horizontal_images>: I<file>, I<file>, I<file>, I<file>;
+
+=item B<vertical_images>:   I<file>, I<file>, I<file>, I<file>;
+
+Sets the images to use for horizontal and vertical bars. This should be used in
+the theme-file.
+
+=item B<encoding>: I<string>;
+
+Sets the encoding to include in the HTML-file. If you don't know what this is,
+don't change it..
+
+=item B<public_page>: I<bool>;
+
+Wether or not this is a public page. Public pages may be linked on the onis
+homepage at some point in the fututre..
+
+=back
+
+=head2 Storage / Persistency
+
+=over 4
+
+=item B<storage_module>: I<string>;
+
+Sets the storage-module to use.
+
+=item B<storage_dir>: I<directory>;
+
+Sets the directory to store persistency information under.
+
+=item B<storage_file>: I<file>;
+
+Sets the file to write persistency data to, if applicable by the
+storage-module.
+
+=back
+
+=head2 Plugins
+
+=over 4
+
+=item B<min_word_length>: I<number>;
+
+Substring containing only word-characters needs to be this long to be
+considered a word.
+
+=item B<plugin_max>: I<number>;
+
+Sets the number of "most referenced nicks", "most used words" and the like to
+be displayed. This option will be removed in the future.
+
+=item B<longlines>: I<number>;
+
+=item B<shortlines>: I<number>;
+
+The number of lines in the big and the small table. While in the big table one
+line is dedicated for one person the small table displays six persons per line.
+
+=item B<quote_cache_size>: I<number>;
+
+Sets how many quotes are to be cached for each nick. At the end of the run one
+of the quotes in the cache will be chosen at random and displayed.
+
+=item B<quote_min>: I<number>;
+
+=item B<quote_max>: I<number>;
+
+Sets the minimum and maximum length of a quote. Too short quotes may be not
+very typical for a person, too long quotes may clutter the layout.
+
+=item B<conversations_number>: I<number>;
+
+=item B<userdetails_conversations_number>: I<number>;
+
+Number of conversations partners to include in the output (or in the
+conversations section of the userdetails plugin).
+
+=item B<soliloquies_count>: I<number>;
+
+Sets how many lines without interruption are considered a soliloquy.
+
+=item B<longterm_days>: I<number>;
+
+=item B<userdetails_longterm_days>: I<number>;
+
+Sets the number of days shown in the longterm-plugin (or the longter-section of
+the userdetails-plugin).
+
+=item B<ignore_words>: I<number>;
+
+The Words-Plugin will ignore words with less than this characters.
+
+=item B<userdetails_number>: I<number>;
+
+The number of nicks to print userdetails for.
+
+=back
+
+=head1 AUTHOR
+
+Florian Forster E<lt>octo at verplant.orgE<gt>
+
+=cut