Added POD to Onis::Language
[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         # TODO: Make a complete (!) lsit..
75         print STDERR <<EOF;
76
77 Usage: $0 [options] <logfile> [logfile logfile ..]
78
79 Options:
80         --config                Specify alternate config file
81         --output <file>         Defines the file to write the HTML to.
82         --overwrite <bool>      Overwrites files without prompting.
83         --channel <channel>     Defines the channel's name.
84         --logtype <type>        Defines the logfile's type.
85                                 See 'config' for a complete list.
86         --user <name>           Define's the generator's name.
87
88 For a full list of all options please read the ``config'' file.
89 EOF
90         exit (1);
91 }
92
93 if (-e $output)
94 {
95         my $overwrite = 0;
96         if (get_config ('overwrite'))
97         {
98                 my $tmp = lc (get_config ('overwrite'));
99                 if ($tmp eq 'true' or $tmp eq 'yes' or $tmp eq 'on')
100                 {
101                         $overwrite = 1;
102                 }
103         }
104         
105         if (!$overwrite)
106         {
107                 print STDERR <<MESSAGE;
108
109 WARNING: The output file ``$output'' already exists
110
111   You can set the ``overwrite'' option in the config
112   file to disable this dialog.
113
114 MESSAGE
115                 print STDERR 'Are you sure you want to overwrite it? [Y|n] ';
116                 my $answer = <STDIN>;
117                 exit (1) if ($answer =~ m/n/i);
118         }
119 }
120
121 my $logtype = 'Eggdrop';
122 if (get_config ('logtype'))
123 {
124         $logtype = ucfirst (lc (get_config ('logtype')));
125 }
126
127 require "Onis/Parser/$logtype.pm";
128 require Onis::Parser::Persistent;
129 require Onis::Data::Persistent;
130 import Onis::Parser (qw(parse last_date));
131 import Onis::Parser::Persistent (qw(newfile));
132 import Onis::Data::Persistent ();
133
134 $FileInfo = Onis::Data::Persistent->new ('FileInfo', 'inode', qw(mtime));
135
136 if (get_config ('purge_logs'))
137 {
138         my $temp = lc (get_config ('purge_logs'));
139         if (($temp eq 'truncate') or ($temp eq 'shorten'))
140         {
141                 $PURGE_LOGS = 1;
142         }
143         elsif (($temp eq 'delete') or ($temp eq 'remove')
144                         or ($temp eq 'del'))
145         {
146                 $PURGE_LOGS = 2;
147         }
148 }
149
150 for (get_config ('input'))
151 {
152         my $file = $_;
153         my $logfile;
154         my $status = 4;
155         my $position = 0;
156         my $mtime;
157         my $size;
158         my $inode;
159
160         ($inode, $size, $mtime) = (stat ($file))[1,7,9];
161
162         print STDERR $/, $/, __FILE__, " --- New File ``$file'' ---" if ($::DEBUG & 0x200);
163         
164         if (!defined ($mtime))
165         {
166                 print STDERR $/, __FILE__, ": Unable to stat file ``$file''";
167                 next;
168         }
169         else
170         {
171                 my ($old_mtime) = $FileInfo->get ($inode);
172
173                 print STDERR $/, __FILE__, ": ``$file'': " if ($::DEBUG & 0x200);
174
175                 if (defined ($old_mtime))
176                 {
177                         if ($old_mtime == $mtime)
178                         {
179                                 print STDERR "File did not change. Skipping." if ($::DEBUG & 0x200);
180                                 next;
181                         }
182                         elsif ($old_mtime < $mtime)
183                         {
184                                 print STDERR "File changed. Reading it again." if ($::DEBUG & 0x200);
185                         }
186                         else
187                         {
188                                 print STDERR "File ``$file'' is older than expected. There might be a problem!";
189                         }
190                 }
191                 else
192                 {
193                         print STDERR "File appears to be new. Reading it." if ($::DEBUG & 0x200);
194                 }
195                 $FileInfo->put ($inode, $mtime);
196         }
197         
198         # truncate
199         if ($PURGE_LOGS == 1)
200         {
201                 unless (open ($logfile, '+< ' . $file))
202                 {
203                         print STDERR $/, __FILE__, ": Unable to open file ``$file'': $!";
204                         next;
205                 }
206         }
207         else
208         {
209                 unless (open ($logfile, '< ' . $file))
210                 {
211                         print STDERR $/, __FILE__, ": Unable to open file ``$file'': $!";
212                         next;
213                 }
214         }
215         
216         if ($PURGE_LOGS)
217         {
218                 unless (flock ($logfile, LOCK_EX))
219                 {
220                         print STDERR $/, __FILE__, ": Unable to get an exclusive lock for file ``$file'': $!";
221                         close ($logfile);
222                         next;
223                 }
224         }
225         else
226         {
227                 unless (flock ($logfile, LOCK_SH))
228                 {
229                         print STDERR $/, __FILE__, ": Unable to get a shared lock for file ``$file'': $!";
230                         close ($logfile);
231                         next;
232                 }
233         }
234         
235         newfile ($FileInfo->{$inode});
236         while (<$logfile>)
237         {
238                 s/\n|\r//g;
239                 $status = parse ($_);
240
241                 # 0 == rewind file
242                 # 1 == line parsed
243                 # 2 == unable to parse
244                 # 3 == line old
245                 # 4 == don't have date
246
247                 if ($status == 0)
248                 {
249                         print STDERR $/, __FILE__, ": Rewinding file ``$file''" if ($::DEBUG & 0x200);
250                         seek ($logfile, 0, 0);
251                         $position = 0;
252                 }
253                 elsif (($status == 1) or ($status == 2)
254                                 or ($status == 3))
255                 {
256                         $position = tell ($logfile);
257                 }
258                 elsif ($status == 4)
259                 {
260                         # void
261                 }
262                 else
263                 {
264                         print STDERR $/, __FILE__, ": Parser returned unknown status code: ``$status''";
265                 }
266         }
267
268         if ($PURGE_LOGS and (($status == 1)
269                                 or ($status == 2)
270                                 or ($status == 3)))
271         {
272                 if (($PURGE_LOGS > 1)
273                         #and (($position + 1) >= $size)
274                         )
275                 {
276                         # delete file
277                         print STDERR $/, __FILE__, ": Deleting empty file ``$file''" if ($::DEBUG & 0x200);
278                         close ($logfile);
279
280                         if (-w $file)
281                         {
282                                 unless (unlink ($file))
283                                 {
284                                         print STDERR $/, __FILE__, ": Unable to delete empty file ``$file'': $!";
285                                 }
286                                 delete ($FileInfo->{$inode});
287                         }
288                         else
289                         {
290                                 print STDERR $/, __FILE__, ": Won't delete ``$file''. Set it to writeable first!";
291                         }
292                 }
293                 else
294                 {
295                         seek ($logfile, 0, 0);
296                         if (truncate ($logfile, 0))
297                         {
298                                 print $logfile &last_date ();
299                                 print STDERR $/, __FILE__, ": Truncated ``$file''" if ($::DEBUG & 0x200);
300                         }
301                         else
302                         {
303                                 print STDERR $/, __FILE__, ": Couldn't truncate file ``$file'': $!";
304                         }
305                         
306                         close ($logfile);
307                 }
308         }
309         else
310         {       
311                 close ($logfile);
312         }
313 }
314
315 require Onis::Data::Core;
316 require Onis::Html;
317 import Onis::Data::Core qw#print_output#;
318 import Onis::Html qw#open_file close_file#;
319
320 if (open_file ($output))
321 {
322         print_output ();
323         close_file ();
324 }
325 else
326 {
327         # Fail and make noise! ;)
328         print STDERR <<MESSAGE;
329
330 ERROR: Unable to open output file
331
332 The output file ``$output'' could not be opened. Please make sure to set
333 the permissions right and try again.
334
335 MESSAGE
336         exit (1);
337 }
338
339 exit (0);
340
341 END
342 {
343         print $/ if ($::DEBUG);
344 }