Some documentation fixes and enhancments.
[usenet/newsstats.git] / groupstats.pl
CommitLineData
2832c235
TH
1#! /usr/bin/perl -W
2#
3# groupstats.pl
4#
5# This script will get statistical data on newgroup usage
d3b6810d 6# from a database.
2832c235
TH
7#
8# It is part of the NewsStats package.
9#
edd250f2 10# Copyright (c) 2010-2012 Thomas Hochstein <thh@inter.net>
2832c235
TH
11#
12# It can be redistributed and/or modified under the same terms under
13# which Perl itself is published.
14
15BEGIN {
16 our $VERSION = "0.01";
17 use File::Basename;
18 push(@INC, dirname($0));
19}
20use strict;
21
edd250f2 22use NewsStats qw(:DEFAULT :TimePeriods :Output :SQLHelper ReadGroupList);
2832c235
TH
23
24use DBI;
edd250f2
TH
25use Getopt::Long qw(GetOptions);
26Getopt::Long::config ('bundling');
2832c235
TH
27
28################################# Main program #################################
29
30### read commandline options
edd250f2
TH
31my ($OptBoundType,$OptCaptions,$OptCheckgroupsFile,$OptComments,
32 $OptFileTemplate,$OptFormat,$OptGroupBy,$OptGroupsDB,$LowBound,$OptMonth,
33 $OptNewsgroups,$OptOrderBy,$OptReportType,$OptSums,$UppBound);
34GetOptions ('b|boundary=s' => \$OptBoundType,
35 'c|captions!' => \$OptCaptions,
36 'checkgroups=s' => \$OptCheckgroupsFile,
37 'comments!' => \$OptComments,
38 'filetemplate=s' => \$OptFileTemplate,
39 'f|format=s' => \$OptFormat,
40 'g|group-by=s' => \$OptGroupBy,
41 'groupsdb=s' => \$OptGroupsDB,
42 'l|lower=i' => \$LowBound,
43 'm|month=s' => \$OptMonth,
44 'n|newsgroups=s' => \$OptNewsgroups,
45 'o|order-by=s' => \$OptOrderBy,
46 'r|report=s' => \$OptReportType,
47 's|sums!' => \$OptSums,
48 'u|upper=i' => \$UppBound,
49 'h|help' => \&ShowPOD,
50 'V|version' => \&ShowVersion) or exit 1;
51# parse parameters
52# $OptComments defaults to TRUE
53$OptComments = 1 if (!defined($OptComments));
54# force --nocomments when --filetemplate is used
55$OptComments = 0 if ($OptFileTemplate);
56# parse $OptBoundType
57if ($OptBoundType) {
58 if ($OptBoundType =~ /level/i) {
59 $OptBoundType = 'level';
60 } elsif ($OptBoundType =~ /av(era)?ge?/i) {
61 $OptBoundType = 'average';
62 } elsif ($OptBoundType =~ /sums?/i) {
63 $OptBoundType = 'sum';
64 } else {
65 $OptBoundType = 'default';
66 }
67}
68# parse $OptReportType
69if ($OptReportType) {
70 if ($OptReportType =~ /av(era)?ge?/i) {
71 $OptReportType = 'average';
72 } elsif ($OptReportType =~ /sums?/i) {
73 $OptReportType = 'sum';
74 } else {
75 $OptReportType = 'default';
76 }
77}
78# read list of newsgroups from --checkgroups
79# into a hash reference
80my $ValidGroups = &ReadGroupList($OptCheckgroupsFile) if $OptCheckgroupsFile;
2832c235
TH
81
82### read configuration
edd250f2 83my %Conf = %{ReadConfig($HomePath.'/newsstats.conf')};
2832c235
TH
84
85### override configuration via commandline options
86my %ConfOverride;
edd250f2 87$ConfOverride{'DBTableGrps'} = $OptGroupsDB if $OptGroupsDB;
2832c235
TH
88&OverrideConfig(\%Conf,\%ConfOverride);
89
f2ddfd8a
TH
90### init database
91my $DBHandle = InitDB(\%Conf,1);
92
edd250f2
TH
93### get time period and newsgroups, prepare SQL 'WHERE' clause
94# get time period
95# and set caption for output and expression for SQL 'WHERE' clause
96my ($CaptionPeriod,$SQLWherePeriod) = &GetTimePeriod($OptMonth);
97# bail out if --month is invalid
98&Bleat(2,"--month option has an invalid format - ".
99 "please use 'YYYY-MM', 'YYYY-MM:YYYY-MM' or 'ALL'!") if !$CaptionPeriod;
100# get list of newsgroups and set expression for SQL 'WHERE' clause
101# with placeholders as well as a list of newsgroup to bind to them
102my ($SQLWhereNewsgroups,@SQLBindNewsgroups) = &SQLGroupList($OptNewsgroups)
103 if $OptNewsgroups;;
104
105### build SQL WHERE clause (and HAVING clause, if needed)
106my ($SQLWhereClause,$SQLHavingClause);
107# $OptBoundType 'level'
108if ($OptBoundType and $OptBoundType ne 'default') {
109 $SQLWhereClause = SQLBuildClause('where',$SQLWherePeriod,
110 $SQLWhereNewsgroups,&SQLHierarchies($OptSums));
111 $SQLHavingClause = SQLBuildClause('having',&SQLSetBounds($OptBoundType,
112 $LowBound,$UppBound));
113# $OptBoundType 'threshold' / 'default' or none
f2ddfd8a 114} else {
edd250f2
TH
115 $SQLWhereClause = SQLBuildClause('where',$SQLWherePeriod,
116 $SQLWhereNewsgroups,&SQLHierarchies($OptSums),
117 &SQLSetBounds('default',$LowBound,$UppBound));
118}
2832c235 119
edd250f2
TH
120### get sort order and build SQL 'ORDER BY' clause
121# default to 'newsgroup' for $OptBoundType 'level' or 'average'
122$OptGroupBy = 'newsgroup' if (!$OptGroupBy and
123 $OptBoundType and $OptBoundType ne 'default');
124# force to 'month' for $OptReportType 'average' or 'sum'
125$OptGroupBy = 'month' if ($OptReportType and $OptReportType ne 'default');
126# parse $OptGroupBy to $GroupBy, create ORDER BY clause $SQLOrderClause
127my ($GroupBy,$SQLOrderClause) = SQLSortOrder($OptGroupBy, $OptOrderBy);
128# $GroupBy will contain 'month' or 'newsgroup' (parsed result of $OptGroupBy)
129# set it to 'month' or 'key' for OutputData()
130$GroupBy = ($GroupBy eq 'month') ? 'month' : 'key';
131
132### get report type and build SQL 'SELECT' query
133my $SQLSelect;
134my $SQLGroupClause = '';
135my $Precision = 0; # number of digits right of decimal point for output
136if ($OptReportType and $OptReportType ne 'default') {
137 $SQLGroupClause = 'GROUP BY newsgroup';
138 # change $SQLOrderClause: replace everything before 'postings'
139 $SQLOrderClause =~ s/BY.+postings/BY postings/;
140 if ($OptReportType eq 'average') {
141 $SQLSelect = "'All months',newsgroup,AVG(postings)";
142 $Precision = 2;
143 # change $SQLOrderClause: replace 'postings' with 'AVG(postings)'
144 $SQLOrderClause =~ s/postings/AVG(postings)/;
145 } elsif ($OptReportType eq 'sum') {
146 $SQLSelect = "'All months',newsgroup,SUM(postings)";
147 # change $SQLOrderClause: replace 'postings' with 'SUM(postings)'
148 $SQLOrderClause =~ s/postings/SUM(postings)/;
149 }
150 } else {
151 $SQLSelect = 'month,newsgroup,postings';
2832c235
TH
152};
153
edd250f2
TH
154### get length of longest newsgroup name delivered by query
155### for formatting purposes
156my $Field = ($GroupBy eq 'month') ? 'newsgroup' : 'month';
157my $MaxLength = &GetMaxLength($DBHandle,$Conf{'DBTableGrps'},
158 $Field,$SQLWhereClause,$SQLHavingClause,
159 @SQLBindNewsgroups);
160
161### build and execute SQL query
162my ($DBQuery);
163# special query preparation for $OptBoundType 'level', 'average' or 'sums'
164if ($OptBoundType and $OptBoundType ne 'default') {
165 # prepare and execute first query:
166 # get list of newsgroups meeting level conditions
167 $DBQuery = $DBHandle->prepare(sprintf('SELECT newsgroup FROM %s.%s %s '.
168 'GROUP BY newsgroup %s',
169 $Conf{'DBDatabase'},$Conf{'DBTableGrps'},
170 $SQLWhereClause,$SQLHavingClause));
171 $DBQuery->execute(@SQLBindNewsgroups)
172 or &Bleat(2,sprintf("Can't get groups data for %s from %s.%s: %s\n",
173 $CaptionPeriod,$Conf{'DBDatabase'},$Conf{'DBTableGrps'},
174 $DBI::errstr));
b802bc3d
TH
175 # add newsgroups to a comma-seperated list ready for IN(...) query
176 my $GroupList;
177 while (my ($Newsgroup) = $DBQuery->fetchrow_array) {
edd250f2 178 $GroupList .= ',' if $GroupList;
b802bc3d
TH
179 $GroupList .= "'$Newsgroup'";
180 };
edd250f2
TH
181 # enhance $WhereClause
182 if ($GroupList) {
183 $SQLWhereClause = SQLBuildClause('where',$SQLWhereClause,
184 sprintf('newsgroup IN (%s)',$GroupList));
185 } else {
186 # condition cannot be satisfied;
187 # force query to fail by adding '0=1'
188 $SQLWhereClause = SQLBuildClause('where',$SQLWhereClause,'0=1');
189 }
190}
191
192# prepare query
193$DBQuery = $DBHandle->prepare(sprintf('SELECT %s FROM %s.%s %s %s %s',
194 $SQLSelect,
195 $Conf{'DBDatabase'},$Conf{'DBTableGrps'},
196 $SQLWhereClause,$SQLGroupClause,$
197 SQLOrderClause));
2832c235
TH
198
199# execute query
edd250f2
TH
200$DBQuery->execute(@SQLBindNewsgroups)
201 or &Bleat(2,sprintf("Can't get groups data for %s from %s.%s: %s\n",
202 $CaptionPeriod,$Conf{'DBDatabase'},$Conf{'DBTableGrps'},
203 $DBI::errstr));
204
205### output results
206# set default to 'pretty'
207$OptFormat = 'pretty' if !$OptFormat;
208# print captions if --caption is set
209if ($OptCaptions && $OptComments) {
210 # print time period with report type
211 my $CaptionReportType= '(number of postings for each month)';
212 if ($OptReportType and $OptReportType ne 'default') {
213 $CaptionReportType= '(average number of postings for each month)'
214 if $OptReportType eq 'average';
215 $CaptionReportType= '(number of all postings for that time period)'
216 if $OptReportType eq 'sum';
217 }
218 printf("# ----- Report for %s %s\n",$CaptionPeriod,$CaptionReportType);
219 # print newsgroup list if --newsgroups is set
220 printf("# ----- Newsgroups: %s\n",join(',',split(/:/,$OptNewsgroups)))
221 if $OptNewsgroups;
222 # print boundaries, if set
223 my $CaptionBoundary= '(counting only month fulfilling this condition)';
224 if ($OptBoundType and $OptBoundType ne 'default') {
225 $CaptionBoundary= '(every single month)' if $OptBoundType eq 'level';
226 $CaptionBoundary= '(on average)' if $OptBoundType eq 'average';
227 $CaptionBoundary= '(all month summed up)' if $OptBoundType eq 'sum';
228 }
229 printf("# ----- Threshold: %s %s x %s %s %s\n",
230 $LowBound ? $LowBound : '',$LowBound ? '=>' : '',
231 $UppBound ? '<=' : '',$UppBound ? $UppBound : '',$CaptionBoundary)
232 if ($LowBound or $UppBound);
233 # print primary and secondary sort order
234 printf("# ----- Grouped by %s (%s), sorted %s%s\n",
235 ($GroupBy eq 'month') ? 'Months' : 'Newsgroups',
236 ($OptGroupBy and $OptGroupBy =~ /-?desc$/i) ? 'descending' : 'ascending',
237 ($OptOrderBy and $OptOrderBy =~ /posting/i) ? 'by number of postings ' : '',
238 ($OptOrderBy and $OptOrderBy =~ /-?desc$/i) ? 'descending' : 'ascending');
239}
240
241# output data
242&OutputData($OptFormat,$OptComments,$GroupBy,$Precision,
243 $OptCheckgroupsFile ? $ValidGroups : '',
244 $OptFileTemplate,$DBQuery,$MaxLength);
2832c235
TH
245
246### close handles
247$DBHandle->disconnect;
248
249__END__
250
251################################ Documentation #################################
252
253=head1 NAME
254
255groupstats - create reports on newsgroup usage
256
257=head1 SYNOPSIS
258
edd250f2 259B<groupstats> [B<-Vhcs> B<--comments>] [B<-m> I<YYYY-MM>[:I<YYYY-MM>] | I<all>] [B<-n> I<newsgroup(s)>] [B<--checkgroups> I<checkgroups file>] [B<-r> I<report type>] [B<-l> I<lower boundary>] [B<-u> I<upper boundary>] [B<-b> I<boundary type>] [B<-g> I<group by>] [B<-o> I<order by>] [B<-f> I<output format>] [B<--filetemplate> I<filename template>] [B<--groupsdb> I<database table>]
2832c235
TH
260
261=head1 REQUIREMENTS
262
edd250f2 263See L<doc/README>.
2832c235
TH
264
265=head1 DESCRIPTION
266
267This script create reports on newsgroup usage (number of postings per
268group per month) taken from result tables created by
edd250f2 269B<gatherstats.pl>.
2832c235 270
edd250f2 271=head2 Features and options
2832c235 272
edd250f2 273=head3 Time period and newsgroups
2832c235 274
edd250f2
TH
275The time period to act on defaults to last month; you can assign another
276time period or a single month (or drop all time constraints) via the
277B<--month> option (see below).
2832c235 278
edd250f2
TH
279B<groupstats> will process all newsgroups by default; you can limit
280processing to only some newsgroups by supplying a list of those groups via
281B<--newsgroups> option (see below). You can include hierarchy levels in
282the output by adding the B<--sums> switch (see below). Optionally
283newsgroups not present in a checkgroups file can be excluded from output,
284sse B<--checkgroups> below.
285
286=head3 Report type
287
288You can choose between different B<--report> types: postings per month,
289average postings per month or all postings summed up; for details, see
290below.
291
292=head3 Upper and lower boundaries
293
294Furthermore you can set an upper and/or lower boundary to exclude some
295results from output via the B<--lower> and B<--upper> options,
296respectively. By default, all newsgroups with more and/or less postings
297per month will be excluded from the result set (i.e. not shown and not
298considered for average and sum reports). You can change the meaning of
299those boundaries with the B<--boundary> option. For details, please see
300below.
301
302=head3 Sorting and formatting the output
303
304By default, all results are grouped by month; you can group results by
305newsgroup instead via the B<--groupy-by> option. Within those groups, the
306list of newsgroups (or months) is sorted alphabetically (or
307chronologically, respectively) ascending. You can change that order (and
308sort by number of postings) with the B<--order-by> option. For details and
309exceptions, please see below.
310
311The results will be formatted as a kind of table; you can change the
312output format to a simple list or just a list of newsgroups and number of
313postings with the B<--format> option. Captions will be added by means of
314the B<--caption> option; all comments (and captions) can be supressed by
315using B<--nocomments>.
316
317Last but not least you can redirect all output to a number of files, e.g.
318one for each month, by submitting the B<--filetemplate> option, see below.
319Captions and comments are automatically disabled in this case.
2832c235
TH
320
321=head2 Configuration
322
f2ddfd8a 323B<groupstats> will read its configuration from F<newsstats.conf>
2832c235
TH
324which should be present in the same directory via Config::Auto.
325
326See doc/INSTALL for an overview of possible configuration options.
327
edd250f2 328You can override some configuration options via the B<--groupsdb> option.
2832c235
TH
329
330=head1 OPTIONS
331
332=over 3
333
edd250f2 334=item B<-V>, B<--version>
2832c235 335
edd250f2 336Print out version and copyright information and exit.
2832c235 337
edd250f2 338=item B<-h>, B<--help>
2832c235
TH
339
340Print this man page and exit.
341
edd250f2 342=item B<-m>, B<--month> I<YYYY-MM[:YYYY-MM]|all>
2832c235 343
edd250f2
TH
344Set processing period to a single month in YYYY-MM format or to a time
345period between two month in YYYY-MM:YYYY-MM format (two month, separated
346by a colon). By using the keyword I<all> instead, you can set no
347processing period to process the whole database.
2832c235 348
edd250f2 349=item B<-n>, B<--newsgroups> I<newsgroup(s)>
2832c235
TH
350
351Limit processing to a certain set of newsgroups. I<newsgroup(s)> can
352be a single newsgroup name (de.alt.test), a newsgroup hierarchy
353(de.alt.*) or a list of either of these, separated by colons, for
354example
355
356 de.test:de.alt.test:de.newusers.*
357
edd250f2 358=item B<-s>, B<--sums|--nosums> (sum per hierarchy level)
2832c235 359
edd250f2
TH
360Include "virtual" groups for every hierarchy level in output, for
361example:
2832c235 362
edd250f2
TH
363 de.alt.ALL 10
364 de.alt.test 5
365 de.alt.admin 7
2832c235 366
edd250f2 367See the B<gatherstats> man page for details.
2832c235 368
edd250f2 369=item B<--checkgroups> I<filename>
2832c235 370
edd250f2
TH
371Restrict output to those newgroups present in a file in checkgroups format
372(one newgroup name per line; everything after the first whitespace on each
373line is ignored). All other newsgroups will be removed from output.
2832c235 374
95d9fe2c
TH
375Contrary to B<gatherstats>, I<filename> is not a template, but refers to
376a single file in checkgroups format.
377
edd250f2 378=item B<-r>, B<--report> I<default|average|sums>
2832c235 379
edd250f2 380Choose the report type: I<default>, I<average> or I<sums>
2832c235 381
edd250f2
TH
382By default, B<groupstats> will report the number of postings for each
383newsgroup in each month. But it can also report the average number of
384postings per group for all months or the total sum of postings per group
385for all months.
2832c235 386
edd250f2
TH
387For report types I<average> and I<sums>, the B<group-by> option has no
388meaning and will be silently ignored (see below).
2832c235 389
edd250f2 390=item B<-l>, B<--lower> I<lower boundary>
2832c235 391
edd250f2 392Set the lower boundary. See B<--boundary> below.
2832c235 393
edd250f2 394=item B<-l>, B<--upper> I<upper boundary>
2832c235 395
edd250f2 396Set the upper boundary. See B<--boundary> below.
2832c235 397
edd250f2
TH
398=item B<-b>, B<--boundary> I<boundary type>
399
400Set the boundary type to one of I<default>, I<level>, I<average> or
401I<sums>.
402
403By default, all newsgroups with more postings per month than the upper
404boundary and/or less postings per month than the lower boundary will be
405excluded from further processing. For the default report that means each
406month only newsgroups with a number of postings between the boundaries
407will be displayed. For the other report types, newsgroups with a number of
408postings exceeding the boundaries in all (!) months will not be
409considered.
410
411For example, lets take a list of newsgroups like this:
412
413 ----- 2012-01:
414 de.comp.datenbanken.misc 6
415 de.comp.datenbanken.ms-access 84
416 de.comp.datenbanken.mysql 88
417 ----- 2012-02:
418 de.comp.datenbanken.misc 8
419 de.comp.datenbanken.ms-access 126
420 de.comp.datenbanken.mysql 21
421 ----- 2012-03:
422 de.comp.datenbanken.misc 24
423 de.comp.datenbanken.ms-access 83
424 de.comp.datenbanken.mysql 36
425
426With C<groupstats --month 2012-01:2012-03 --lower 25 --report sums>,
427you'll get the following result:
2832c235 428
edd250f2
TH
429 ----- All months:
430 de.comp.datenbanken.ms-access 293
431 de.comp.datenbanken.mysql 124
2832c235 432
edd250f2
TH
433de.comp.datenbanken.misc has not been considered even though it has 38
434postings in total, because it has less than 25 postings in every single
95d9fe2c
TH
435month. If you want to list all newsgroups with more than 25 postings
436I<in total>, you'll have to set the boundary type to I<sum>, see below.
628a183c 437
edd250f2
TH
438A boundary type of I<level> will show only those newsgroups - at all -
439that satisfy the boundaries in each and every single month. With the above
440list of newsgroups and
441C<groupstats --month 2012-01:2012-03 --lower 25 --boundary level --report sums>,
442you'll get this result:
2832c235 443
edd250f2
TH
444 ----- All months:
445 de.comp.datenbanken.ms-access 293
2832c235 446
edd250f2 447de.comp.datenbanken.mysql has not been considered because it had less than
95d9fe2c 44825 postings in 2012-02 (only).
2832c235 449
edd250f2 450You can use that to get a list of newsgroups that have more (or less) then
95d9fe2c 451x postings in every month during the whole reporting period.
2832c235 452
edd250f2
TH
453A boundary type of I<average> will show only those newsgroups - at all -that
454satisfy the boundaries on average. With the above list of newsgroups and
455C<groupstats --month 2012-01:2012-03 --lower 25 --boundary avg --report sums>,
456you'll get this result:
78389b28 457
edd250f2
TH
458 ----- All months:
459 de.comp.datenbanken.ms-access 293
460 de.comp.datenbanken.mysql 145
2832c235 461
edd250f2 462The average number of postings in the three groups is:
2832c235 463
edd250f2
TH
464 de.comp.datenbanken.misc 12.67
465 de.comp.datenbanken.ms-access 97.67
466 de.comp.datenbanken.mysql 48.33
2832c235 467
edd250f2
TH
468Last but not least, a boundary type of I<sums> will show only those
469newsgroups - at all - that satisfy the boundaries with the total sum of
470all postings during the reporting period. With the above list of
471newsgroups and
472C<groupstats --month 2012-01:2012-03 --lower 25 --boundary sum --report sums>,
473you'll finally get this result:
2832c235 474
edd250f2
TH
475 ----- All months:
476 de.comp.datenbanken.misc 38
477 de.comp.datenbanken.ms-access 293
478 de.comp.datenbanken.mysql 145
2832c235 479
2832c235 480
edd250f2 481=item B<-g>, B<--group-by> I<month[-desc]|newsgroups[-desc]>
2832c235 482
edd250f2
TH
483By default, all results are grouped by month, sorted chronologically in
484ascending order, like this:
78389b28 485
edd250f2
TH
486 ----- 2012-01:
487 de.comp.datenbanken.ms-access 84
488 de.comp.datenbanken.mysql 88
489 ----- 2012-02:
490 de.comp.datenbanken.ms-access 126
491 de.comp.datenbanken.mysql 21
78389b28 492
edd250f2
TH
493The results can be grouped by newsgroups instead via
494B<--group-by> I<newsgroup>:
495
496 ----- de.comp.datenbanken.ms-access:
497 2012-01 84
498 2012-02 126
499 ----- de.comp.datenbanken.mysql:
500 2012-01 88
501 2012-02 21
502
503By appending I<-desc> to the group-by option parameter, you can reverse
504the sort order - e.g. B<--group-by> I<month-desc> will give:
505
506 ----- 2012-02:
507 de.comp.datenbanken.ms-access 126
508 de.comp.datenbanken.mysql 21
509 ----- 2012-01:
510 de.comp.datenbanken.ms-access 84
511 de.comp.datenbanken.mysql 88
512
513Average and sums reports (see above) will always be grouped by months;
514this option will therefore be ignored.
515
516=item B<-o>, B<--order-by> I<default[-desc]|postings[-desc]>
517
518Within each group (a single month or single newsgroup, see above), the
519report will be sorted by newsgroup names in ascending alphabetical order
520by default. You can change the sort order to descending or sort by number
521of postings instead.
522
523=item B<-f>, B<--format> I<pretty|list|dump>
524
525Select the output format, I<pretty> being the default:
526
527 ----- 2012-01:
528 de.comp.datenbanken.ms-access 84
529 de.comp.datenbanken.mysql 88
530 ----- 2012-02:
531 de.comp.datenbanken.ms-access 126
532 de.comp.datenbanken.mysql 21
533
534I<list> format looks like this:
535
536 2012-01 de.comp.datenbanken.ms-access 84
537 2012-01 de.comp.datenbanken.mysql 88
538 2012-02 de.comp.datenbanken.ms-access 126
539 2012-02 de.comp.datenbanken.mysql 21
540
541And I<dump> format looks like this:
542
543 # 2012-01:
544 de.comp.datenbanken.ms-access 84
545 de.comp.datenbanken.mysql 88
546 # 2012-02:
547 de.comp.datenbanken.ms-access 126
548 de.comp.datenbanken.mysql 21
549
550You can remove the comments by using B<--nocomments>, see below.
551
552=item B<-c>, B<--captions|--nocaptions>
553
554Add captions to output, like this:
555
556 ----- Report for 2012-01 to 2012-02 (number of postings for each month)
557 ----- Newsgroups: de.comp.datenbanken.*
558 ----- Threshold: 10 => x <= 20 (on average)
559 ----- Grouped by Newsgroups (ascending), sorted by number of postings descending
560
561False by default.
562
563=item B<--comments|--nocomments>
564
565Add comments (group headers) to I<dump> and I<pretty> output. True by default.
566
567Use I<--nocomments> to suppress anything except newsgroup names/months and
568numbers of postings. This is enforced when using B<--filetemplate>, see below.
569
570=item B<--filetemplate> I<filename template>
571
572Save output to file(s) instead of dumping it to STDOUT. B<groupstats> will
573create one file for each month (or each newsgroup, accordant to the
574setting of B<--group-by>, see above), with filenames composed by adding
575year and month (or newsgroup names) to the I<filename template>, for
576example with B<--filetemplate> I<stats>:
577
578 stats-2012-01
579 stats-2012-02
78389b28
TH
580 ... and so on
581
edd250f2 582B<--nocomments> is enforced, see above.
78389b28 583
edd250f2 584=item B<--groupsdb> I<database table>
2832c235
TH
585
586Override I<DBTableGrps> from F<newsstats.conf>.
587
588=back
589
590=head1 INSTALLATION
591
edd250f2 592See L<doc/INSTALL>.
2832c235
TH
593
594=head1 EXAMPLES
595
edd250f2 596Show number of postings per group for lasth month in I<pretty> format:
2832c235
TH
597
598 groupstats
599
600Show that report for January of 2010 and de.alt.* plus de.test,
601including display of hierarchy levels:
602
edd250f2 603 groupstats --month 2010-01 --newsgroups de.alt.*:de.test --sums
2832c235 604
edd250f2
TH
605Only show newsgroups with 30 postings or less last month, ordered
606by number of postings, descending, in I<pretty> format:
2832c235 607
edd250f2 608 groupstats --upper 30 --order-by postings-desc
2832c235 609
edd250f2
TH
610Show the total of all postings for the year of 2010 for all groups that
611had 30 postings or less in every single month in that year, ordered by
612number of postings in descending order:
613
614 groupstats -m 2010-01:2010-12 -u 30 -b level -r sums -o postings-desc
2832c235 615
edd250f2 616The same for the average number of postings in the year of 2010:
2832c235 617
edd250f2 618 groupstats -m 2010-01:2010-12 -u 30 -b level -r avg -o postings-desc
2832c235 619
edd250f2
TH
620List number of postings per group for eacht month of 2010 and redirect
621output to one file for each month, namend stats-2010-01 and so on, in
622machine-readable form (without formatting):
2832c235 623
edd250f2 624 groupstats -m 2010-01:2010-12 -f dump --filetemplate stats
2832c235 625
2832c235
TH
626
627=head1 FILES
628
629=over 4
630
631=item F<groupstats.pl>
632
633The script itself.
634
635=item F<NewsStats.pm>
636
637Library functions for the NewsStats package.
638
639=item F<newsstats.conf>
640
edd250f2 641Runtime configuration file.
2832c235
TH
642
643=back
644
645=head1 BUGS
646
647Please report any bugs or feature requests to the author or use the
648bug tracker at L<http://bugs.th-h.de/>!
649
650=head1 SEE ALSO
651
652=over 2
653
654=item -
655
edd250f2 656L<doc/README>
2832c235
TH
657
658=item -
659
edd250f2 660l>doc/INSTALL>
2832c235
TH
661
662=item -
663
664gatherstats -h
665
666=back
667
668This script is part of the B<NewsStats> package.
669
670=head1 AUTHOR
671
672Thomas Hochstein <thh@inter.net>
673
674=head1 COPYRIGHT AND LICENSE
675
edd250f2 676Copyright (c) 2010-2012 Thomas Hochstein <thh@inter.net>
2832c235
TH
677
678This program is free software; you may redistribute it and/or modify it
679under the same terms as Perl itself.
680
681=cut
This page took 0.047427 seconds and 4 git commands to generate.