Added automatic revision making..
[onis.git] / onis
1 #!/usr/bin/perl
2 ##########################################################################
3 #    onis 0.7.2                                               2005-01-21 #
4 #---=============--------------------------------------------------------#
5 # Language: Perl                                                         #
6 # Purpose:  Generating statistics                                        #
7 # Input:    IRC-Logfiles                                                 #
8 # Output:   One HTML file                                                #
9 # Version:  0.7.2 (unstable)                                             #
10 # License:  GPL                                                          #
11 # Homepage: http://verplant.org/onis/                                    #
12 # Authors:  Florian octo Forster <octo@verplant.org>                     #
13 #           Contributions are listed in THANKS                           #
14 ##########################################################################
15
16 BEGIN
17 {
18         if ($0 =~ m#^(.*)[/\\]#) { chdir ($1); }
19
20         unshift (@INC, 'lib');
21
22         # 0x0010   Language (make not-translated lines red/yellow)
23         # 0x0020   Parser (dropped lines)
24         # 0x0040   Parser (time information)
25         # 0x0100   Data::Core (host unsharp)
26         # 0x0200   Data::Persistent
27         # 0x0400   Data::Core (dump incoming data to stderr)
28         # 0x0800   Data::Core (initializing)
29         # 0x1000   Onis::Users
30         $::DEBUG = 0x0000;
31 }
32
33 use strict;
34 use warnings;
35
36 use Onis::Config qw/get_config parse_argv read_config/;
37 use File::Basename qw/dirname/;
38 use Fcntl qw/:flock/;
39
40 use vars qw/$VERSION $REVISION/;
41
42 $VERSION = '';
43 $REVISION = '$LastChangedRevision$';
44
45 if (!$VERSION)
46 {
47         $VERSION = $REVISION;
48         $VERSION =~ s/^\D*(\d+).*/r$1/;
49 }
50
51 our $FILEINFO;
52 our $PURGE_LOGS = 0;
53
54 print STDERR $/, __FILE__, ': $Id$' if ($::DEBUG);
55
56 parse_argv (@ARGV);
57 read_config (get_config ('config') ? get_config ('config') : 'config');
58 read_config (scalar get_config ('theme')) if (get_config ('theme'));
59
60 my $output = get_config ('output');
61 if (!$output)
62 {
63         $output = "reports/onis.html";
64 }
65
66 foreach ('Core', get_config ('plugin'))
67 {
68         my $module = ucfirst (lc ($_));
69         require "Onis/Plugins/$module.pm";
70 }
71
72 if (!get_config ('input'))
73 {
74         print STDERR <<EOF;
75
76 Usage: $0 [options] <logfile> [logfile logfile ..]
77
78 Options:
79         --config                Specify alternate config file
80         --output <file>         Defines the file to write the HTML to.
81         --overwrite <bool>      Overwrites files without prompting.
82         --channel <channel>     Defines the channel's name.
83         --logtype <type>        Defines the logfile's type.
84                                 See 'config' for a complete list.
85         --user <name>           Define's the generator's name.
86
87 For a full list of all options please read the ``config'' file.
88 EOF
89         exit (1);
90 }
91
92 if (-e $output)
93 {
94         my $overwrite = 0;
95         if (get_config ('overwrite'))
96         {
97                 my $tmp = lc (get_config ('overwrite'));
98                 if ($tmp eq 'true' or $tmp eq 'yes' or $tmp eq 'on')
99                 {
100                         $overwrite = 1;
101                 }
102         }
103         
104         if (!$overwrite)
105         {
106                 print STDERR <<MESSAGE;
107
108 WARNING: The output file ``$output'' already exists
109
110   You can set the ``overwrite'' option in the config
111   file to disable this dialog.
112
113 MESSAGE
114                 print STDERR 'Are you sure you want to overwrite it? [Y|n] ';
115                 my $answer = <STDIN>;
116                 exit (1) if ($answer =~ m/n/i);
117         }
118 }
119
120 my $logtype = 'Eggdrop';
121 if (get_config ('logtype'))
122 {
123         $logtype = ucfirst (lc (get_config ('logtype')));
124 }
125
126 require "Onis/Parser/$logtype.pm";
127 require Onis::Parser::Persistent;
128 require Onis::Data::Persistent;
129 import Onis::Parser qw/parse last_date/;
130 import Onis::Parser::Persistent qw#newfile#;
131 import Onis::Data::Persistent qw#init#;
132
133 $FILEINFO = init ('$FILEINFO', 'hash');
134
135 if (get_config ('purge_logs'))
136 {
137         my $temp = lc (get_config ('purge_logs'));
138         if (($temp eq 'truncate') or ($temp eq 'shorten'))
139         {
140                 $PURGE_LOGS = 1;
141         }
142         elsif (($temp eq 'delete') or ($temp eq 'remove')
143                         or ($temp eq 'del'))
144         {
145                 $PURGE_LOGS = 2;
146         }
147 }
148
149 for (get_config ('input'))
150 {
151         my $file = $_;
152         my $logfile;
153         my $status = 4;
154         my $position = 0;
155         my $mtime;
156         my $size;
157         my $inode;
158
159         ($inode, $size, $mtime) = (stat ($file))[1,7,9];
160
161         print STDERR $/, $/, __FILE__, " --- New File ``$file'' ---" if ($::DEBUG & 0x200);
162         
163         if (!defined ($mtime))
164         {
165                 print STDERR $/, __FILE__, ": Unable to stat file ``$file''";
166                 next;
167         }
168         else
169         {
170                 print STDERR $/, __FILE__, ": ``$file'': " if ($::DEBUG & 0x200);
171                 if (defined ($FILEINFO->{$inode}{'mtime'}))
172                 {
173                         if ($FILEINFO->{$inode}{'mtime'} == $mtime)
174                         {
175                                 print STDERR "File did not change. Skipping." if ($::DEBUG & 0x200);
176                                 next;
177                         }
178                         elsif ($FILEINFO->{$inode}{'mtime'} < $mtime)
179                         {
180                                 print STDERR "File changed. Reading it again." if ($::DEBUG & 0x200);
181                         }
182                         else
183                         {
184                                 print STDERR "File ``$file'' is older than expected. There might be a problem!";
185                         }
186                 }
187                 else
188                 {
189                         print STDERR "File appears to be new. Reading it." if ($::DEBUG & 0x200);
190                 }
191                 $FILEINFO->{$inode}{'mtime'} = $mtime;
192         }
193         
194         # truncate
195         if ($PURGE_LOGS == 1)
196         {
197                 unless (open ($logfile, '+< ' . $file))
198                 {
199                         print STDERR $/, __FILE__, ": Unable to open file ``$file'': $!";
200                         next;
201                 }
202         }
203         else
204         {
205                 unless (open ($logfile, '< ' . $file))
206                 {
207                         print STDERR $/, __FILE__, ": Unable to open file ``$file'': $!";
208                         next;
209                 }
210         }
211         
212         if ($PURGE_LOGS)
213         {
214                 unless (flock ($logfile, LOCK_EX))
215                 {
216                         print STDERR $/, __FILE__, ": Unable to get an exclusive lock for file ``$file'': $!";
217                         close ($logfile);
218                         next;
219                 }
220         }
221         else
222         {
223                 unless (flock ($logfile, LOCK_SH))
224                 {
225                         print STDERR $/, __FILE__, ": Unable to get a shared lock for file ``$file'': $!";
226                         close ($logfile);
227                         next;
228                 }
229         }
230         
231         newfile ($FILEINFO->{$inode});
232         while (<$logfile>)
233         {
234                 s/\n|\r//g;
235                 $status = parse ($_);
236
237                 # 0 == rewind file
238                 # 1 == line parsed
239                 # 2 == unable to parse
240                 # 3 == line old
241                 # 4 == don't have date
242
243                 if ($status == 0)
244                 {
245                         print STDERR $/, __FILE__, ": Rewinding file ``$file''" if ($::DEBUG & 0x200);
246                         seek ($logfile, 0, 0);
247                         $position = 0;
248                 }
249                 elsif (($status == 1) or ($status == 2)
250                                 or ($status == 3))
251                 {
252                         $position = tell ($logfile);
253                 }
254                 elsif ($status == 4)
255                 {
256                         # void
257                 }
258                 else
259                 {
260                         print STDERR $/, __FILE__, ": Parser returned unknown status code: ``$status''";
261                 }
262         }
263
264         if ($PURGE_LOGS and (($status == 1)
265                                 or ($status == 2)
266                                 or ($status == 3)))
267         {
268                 if (($PURGE_LOGS > 1)
269                         #and (($position + 1) >= $size)
270                         )
271                 {
272                         # delete file
273                         print STDERR $/, __FILE__, ": Deleting empty file ``$file''" if ($::DEBUG & 0x200);
274                         close ($logfile);
275
276                         if (-w $file)
277                         {
278                                 unless (unlink ($file))
279                                 {
280                                         print STDERR $/, __FILE__, ": Unable to delete empty file ``$file'': $!";
281                                 }
282                                 delete ($FILEINFO->{$inode});
283                         }
284                         else
285                         {
286                                 print STDERR $/, __FILE__, ": Won't delete ``$file''. Set it to writeable first!";
287                         }
288                 }
289                 else
290                 {
291                         seek ($logfile, 0, 0);
292                         if (truncate ($logfile, 0))
293                         {
294                                 print $logfile &last_date ();
295                                 print STDERR $/, __FILE__, ": Truncated ``$file''" if ($::DEBUG & 0x200);
296                         }
297                         else
298                         {
299                                 print STDERR $/, __FILE__, ": Couldn't truncate file ``$file'': $!";
300                         }
301                         
302                         close ($logfile);
303                 }
304         }
305         else
306         {       
307                 close ($logfile);
308         }
309 }
310
311 require Onis::Data::Core;
312 require Onis::Html;
313 import Onis::Data::Core qw#print_output#;
314 import Onis::Html qw#open_file close_file#;
315
316 if (open_file ($output))
317 {
318         print_output ();
319         close_file ();
320 }
321 else
322 {
323         # Fail and make noise! ;)
324         print STDERR <<MESSAGE;
325
326 ERROR: Unable to open output file
327
328 The output file ``$output'' could not be opened. Please make sure to set
329 the permissions right and try again.
330
331 MESSAGE
332         exit (1);
333 }
334
335 exit (0);
336
337 END
338 {
339         print $/ if ($::DEBUG);
340 }