################################# Main program #################################
### read commandline options
-my %Options = &ReadOptions('m:p:an:o:t:l:b:iscqdg:');
+my %Options = &ReadOptions('m:p:an:o:t:l:b:iscqdf:g:');
### read configuration
my %Conf = %{ReadConfig('newsstats.conf')};
### check for incompatible command line options
# you can't mix '-t', '-b' and '-l'
# -b/-l take preference over -t, and -b takes preference over -l
+# you can't use '-f' with '-b' or '-l'
if ($Options{'b'} or $Options{'l'}) {
+ if ($Options{'f'}) {
+ # drop -f
+ warn ("$MySelf: W: You cannot save the report to monthly files when using top lists (-b) or levels (-l). Filename template '-f $Options{'f'}' was ignored.\n");
+ undef($Options{'f'});
+ };
if ($Options{'t'}) {
# drop -t
warn ("$MySelf: W: You cannot combine thresholds (-t) and top lists (-b) or levels (-l). Threshold '-t $Options{'t'}' was ignored.\n");
};
### check output type
-# default output type to 'dump'
-$Options{'o'} = 'dump' if !$Options{'o'};
+# default output type to 'pretty'
+$Options{'o'} = 'pretty' if !$Options{'o'};
# fail if more than one newsgroup is combined with 'dumpgroup' type
die ("$MySelf: E: You cannot combine newsgroup lists (-n) with more than one group with '-o dumpgroup'!\n") if ($Options{'o'} eq 'dumpgroup' and defined($Options{'n'}) and $Options{'n'} =~ /:|\*/);
# accept 'dumpgroup' only with -n
warn ("$MySelf: W: You must submit exactly one newsgroup ('-n news.group') for '-o dumpgroup'. Output type was set to 'dump'.\n");
};
# set output type to 'pretty' for -l
-if ($Options{'l'}) {
+if ($Options{'l'} and $Options{'o'} ne 'pretty') {
$Options{'o'} = 'pretty';
warn ("$MySelf: W: Output type forced to '-o pretty' due to usage of '-l'.\n");
};
+# set output type to 'dump' for -f
+if ($Options{'f'} and $Options{'o'} ne 'dump') {
+ $Options{'o'} = 'dump';
+ warn ("$MySelf: W: Output type forced to '-o dump' due to usage of '-f'.\n");
+};
### init database
my $DBHandle = InitDB(\%Conf,1);
} else {
($StartMonth,$EndMonth) = &GetTimePeriod($Options{'m'},$Options{'p'});
};
-# if time period is more than one month: set output type to '-o pretty' or '-o dumpgroup'
+# if time period is more than one month: force output type to '-o pretty' or '-o dumpgroup'
if ($Options{'o'} eq 'dump' and ($Options{'p'} or $Options{'a'})) {
if (defined($Options{'n'}) and $Options{'n'} !~ /:|\*/) {
- warn ("$MySelf: W: You cannot combine time periods (-p) with '-o dump', changing output type to '-o dumpgroup'.\n");
- $Options{'o'} = 'dumpgroup';
- } else {
- warn ("$MySelf: W: You cannot combine time periods (-p) with '-o dump', changing output type to '-o pretty'.\n");
- $Options{'o'} = 'pretty';
+ # just one newsgroup is defined
+ warn ("$MySelf: W: You cannot combine time periods (-p) with '-o dump', changing output type to '-o dumpgroup'.\n");
+ $Options{'o'} = 'dumpgroup';
+ } elsif (!defined($Options{'f'})) {
+ # more than one newsgroup - and no file output
+ warn ("$MySelf: W: You cannot combine time periods (-p) with '-o dump', changing output type to '-o pretty'.\n");
+ $Options{'o'} = 'pretty';
}
};
or die sprintf("$MySelf: E: Can't get groups data for %s to %s from %s.%s: %s\n",$StartMonth,$EndMonth,$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$DBI::errstr);
# output results
+# reset caption (-c) if -f is set
+undef($Options{'c'}) if $Options{'f'};
# print caption (-c) with time period if -m or -p is set
if ($Options{'c'}) {
if ($Options{'p'}) {
printf ("----- Threshold: %s %u\n",$Options{'i'} ? '<' : '>',$Options{'t'}) if $Options{'c'} and $Options{'t'};
if (!defined($Options{'b'}) and !defined($Options{'l'})) {
# default: neither -b nor -l
- &OutputData($Options{'o'},$DBQuery,$MaxLength);
+ &OutputData($Options{'o'},$Options{'f'},$DBQuery,$MaxLength);
} elsif ($Options{'b'}) {
# -b is set (then -l can't be!)
# we have to read in the query results ourselves, as they do not have standard layout
=head1 SYNOPSIS
-B<groupstats> [B<-Vhiscqd>] [B<-m> I<YYYY-MM> | B<-p> I<YYYY-MM:YYYY-MM> | B<-a>] [B<-n> I<newsgroup(s)>] [B<-t> I<threshold>] [B<-l> I<level>] [B<-b> I<number>] [B<-o> I<output type>] [B<-g> I<database table>]
+B<groupstats> [B<-Vhiscqd>] [B<-m> I<YYYY-MM> | B<-p> I<YYYY-MM:YYYY-MM> | B<-a>] [B<-n> I<newsgroup(s)>] [B<-t> I<threshold>] [B<-l> I<level>] [B<-b> I<number>] [B<-o> I<output type>] [B<-f> I<filename template>] [B<-g> I<database table>]
=head1 REQUIREMENTS
Last but not least you can create a "best of" list of the top x
newsgroups via B<-b> (or a "worst of" list by adding B<i>).
-By default, B<groupstats> will dump a very simple alphabetical list of
-newsgroups, one per line, followed by the number of postings in that
-month. This output format of course cannot sensibly be combined with
-time periods, so you can set the output format by using B<-o> (see
+By default, B<groupstats> will dump an alphabetical list of newsgroups,
+one per line, followed by the number of postings in that group, for
+every month. You can change the output format by using B<-o> (see
below). Captions can be added by setting the B<-c> switch.
=head2 Configuration
by newsgroup name, followed by month.
This setting will be ignored if B<-b> is set. Overrides B<-t> and
-can't be used together with B<-q> or B<-d>.
+can't be used together with B<-q>, B<-d> or B<-f>.
=item B<-b> I<n> (best of)
list of the I<n> newsgroups with the least postings over the whole
period is generated. Output will be ordered by sum of postings.
-Overrides B<-t> and B<-l> and can't be used together with B<-q> or
-B<-d>. Output format is set to I<pretty> (see below).
+Overrides B<-t> and B<-l> and can't be used together with B<-q>, B<-d>
+or B<-f>. Output format is set to I<pretty> (see below).
=item B<-i> (invert)
=item B<-o> I<output type> (output format)
-Set output format. Default is I<dump>, consisting of an alphabetical
-list of newsgroups, each on a new line, followed by the number of
-postings in that month. This default format can't be used with time
-periods of more than one month.
+Set output format. Default is I<pretty>, which will print a header for
+each new month, followed by an alphabetical list of newsgroups, each
+on a new line, followed by the number of postings in that month.
+B<groupstats> will try to align newsgroup names and posting counts.
+Usage of B<-b> will force this format; it cannot be used together with
+B<-f>.
+
+I<dump> format is used to create an easily parsable output consisting
+of an alphabetical list of newsgroups, each on a new line, followed by
+the number of postings in that month, without any alignment. This
+default format can't be used with time periods of more than one month.
+Usage of B<-f> will force this format.
I<list> format is like I<dump>, but will print the month in front of
the newsgroup name.
exactly one newsgroup and is like I<dump>, but will output months,
followed by the number of postings.
-If you don't need easily parsable output, you'll mostly use I<pretty>
-format, which will print a header for each new month and try to align
-newsgroup names and posting counts. Usage of B<-b> will force this
-format.
-
=item B<-c> (captions)
-Add captions to output (reporting period, newsgroups list, threshold).
+Add captions to output (reporting period, newsgroups list, threshold
+and so on).
+
+This setting will be ignored if B<-f> is set.
=item B<-q> (quantity of postings)
Cannot be used with B<-l> or B<-b>.
+=item B<-f> I<filename template> (output file)
+
+Save output to file instead of dumping it to STDOUT. B<groupstats>
+will create one file for each month, with filenames composed by
+adding year and month to the I<filename template>, for example
+with B<-f> I<stats>:
+
+ stats-2010-01
+ stats-2010-02
+ ... and so on
+
+This setting will be ignored if B<-l> or B<-b> is set. Output format
+is set to I<dump> (see above).
+
=item B<-g> I<table> (postings per group table)
Override I<DBTableGrps> from F<newsstats.conf>.