Add ClientStats to postingstats.

Signed-off-by: Thomas Hochstein <thh@thh.name>
This commit is contained in:
Thomas Hochstein 2025-05-30 22:43:39 +02:00
parent 09a9112679
commit 39e845d552
2 changed files with 123 additions and 29 deletions

View file

@ -16,6 +16,7 @@
# Usage:
# $~ groupstats.pl --nocomments --sums --format dump | postingstats.pl -t groups
# $~ hoststats.pl --nocomments --sums --format dump | postingstats.pl -t hosts
# $~ clientstats.pl --nocomments --sums --versions --format dump | postingstats.pl -t clients
#
BEGIN {
@ -53,19 +54,22 @@ if (!$Type) {
$Type = 'GroupStats';
} elsif ($Type =~ /(host|server)s?/i) {
$Type = 'HostStats';
} elsif ($Type =~ /(client|reader)s?/i) {
$Type = 'ClientStats';
};
my $Timestamp = time;
##### ----- configuration --------------------------------------------
my $TLH = 'de';
my %Heading = ('GroupStats' => 'Postingstatistik fuer de.* im Monat '.$Month,
'HostStats' => 'Serverstatistik fuer de.* im Monat '.$Month
my %Heading = ('GroupStats' => 'Postingstatistik fuer de.* im Monat '.$Month,
'HostStats' => 'Serverstatistik fuer de.* im Monat '.$Month,
'ClientStats' => 'Newsreaderstatistik fuer de.* im Monat '.$Month
);
my %TH = ('counter' => 'Nr.',
'value' => 'Anzahl',
'percentage' => 'Prozent'
);
my %LeadIn = ('GroupStats' => <<GROUPSIN, 'HostStats' => <<HOSTSIN);
my %LeadIn = ('GroupStats' => <<GROUPSIN, 'HostStats' => <<HOSTSIN, 'ClientStats' => <<CLIENTSIN);
From: Thomas Hochstein <thh\@thh.name>
Newsgroups: local.test
Subject: Postingstatistik fuer de.* im Monat $Month
@ -88,7 +92,18 @@ Content-Transfer-Encoding: 7bit
User-Agent: postingstats.pl/$VERSION (NewsStats)
HOSTSIN
my %LeadOut = ('GroupStats' => <<GROUPSOUT, 'HostStats' => <<HOSTSOUT);
From: Thomas Hochstein <thh\@thh.name>
Newsgroups: local.test
Subject: Newsreaderstatistik fuer de.* im Monat $Month
Message-ID: <destat-clients-$Month.$Timestamp\@mid.news.szaf.org>
Approved: thh\@thh.name
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
User-Agent: postingstats.pl/$VERSION (NewsStats)
CLIENTSIN
my %LeadOut = ('GroupStats' => <<GROUPSOUT, 'HostStats' => <<HOSTSOUT, 'ClientStats' => <<CLIENTSOUT);
Alle Zahlen wurden ermittelt auf einem Newsserver mit redundanter Anbin-
dung fuer de.* unter Anwendung ueblicher Filtermassnahmen. Steuernach-
@ -110,6 +125,19 @@ wurden, bleiben erfasst, sofern sie das System ueberhaupt (und vor der
Loeschnachricht) erreicht haben.
HOSTSOUT
Alle Zahlen wurden ermittelt auf einem Newsserver mit redundanter Anbin-
dung fuer de.* unter Anwendung ueblicher Filtermassnahmen. Steuernach-
richten werden nicht erfasst; Postings, die supersedet oder gecancelt
wurden, bleiben erfasst, sofern sie das System ueberhaupt (und vor der
Loeschnachricht) erreicht haben. Versionsangaben werden nur gezaehlt,
wenn Sie ermittelbar sind; daher kann die Summe der Newsreader-Versionen
kleiner sein als die Postingzahl fuer den Newsreader. Ausserdem koennen
an einem Beitrag mehrere Clients beteiligt sein, bspw. der Newsreader
und ein lokaler Server wie der Hamster. Daher kann die Summe aller
Newsreader groesser sein als die Summer der Postings; auch ergeben die
Prozentzahlen dementsprechend in der Summe mehr als 100%.
CLIENTSOUT
##### ----- subroutines ----------------------------------------------
sub Percentage {
@ -124,35 +152,76 @@ sub Divider {
return ':' . $Symbol x ($MaxLength+TABLEWIDTH) . ":\n";
}
sub SingleVersion {
my ($LastName,$RSubValue,$RValue,$RMaxLength) = @_;
# get version to add to client name
my ($Version) = keys %{$$RSubValue{$LastName}};
$Version =~ s/^- //;
# add version to client name by creating a new name
# and deleting the old one
my ($NameVersion) = $LastName . ' ' . $Version;
$$RValue{$NameVersion} = $$RValue{$LastName};
delete($$RValue{$LastName});
$$RMaxLength = length($NameVersion) if length($NameVersion) > $$RMaxLength;
# delete single version
delete($$RSubValue{$LastName});
}
##### ----- main loop ------------------------------------------------
my (%Value, $SumName, $SumTotal, $MaxLength);
$MaxLength = 0;
my (%Value, %SubValue, $SubCounter, $LastName, $SumName, $SumTotal,
$MaxLength);
if ($Type eq 'GroupStats') {
$SumName = "$TLH.ALL";
$TH{'name'} = 'Newsgroup'
} elsif ($Type eq 'HostStats') {
$SumName = 'ALL';
$TH{'name'} = 'Server'
$TH{'name'} = 'Postingserver'
} elsif ($Type eq 'ClientStats') {
$SumName = 'ALL';
$TH{'name'} = 'Newsreader / Client'
}
# read from STDIN
### read from STDIN
$MaxLength = 0;
while(<>) {
my ($Name, $Value) = split;
my ($Name, $Value) = $_ =~ /(.+) (\d+)$/;
$SumTotal = $Value if $Name eq $SumName;
next if $Name =~ /ALL$/;
$Value{$Name} = $Value;
$MaxLength = length($Name) if length($Name) > $MaxLength;
}
# print to STDOUT
# handle client versions
if ($Type eq 'ClientStats' and $Name =~ /^- /) {
$SubValue{$LastName}{$Name} = $Value;
$SubCounter++;
} else {
# clients with just one version
&SingleVersion($LastName,\%SubValue,\%Value,\$MaxLength)
if ($LastName && $SubCounter == 1);
# reset version counter and client name
$SubCounter = 0;
$LastName = $Name;
$Value{$Name} = $Value;
$MaxLength = length($Name) if length($Name) > $MaxLength;
}
}
# clients with just one version (last iteration)
&SingleVersion($LastName,\%SubValue,\%Value,\$MaxLength)
if ($LastName && $SubCounter == 1);
### print to STDOUT
# calculate padding for $Heading
my $PaddingLeft = ' ' x int((($MaxLength+TABLEWIDTH-2-length($Heading{$Type}))/2));
my $PaddingRight = $PaddingLeft;
$PaddingLeft .= ' ' if (length($Heading{$Type}) + (length($PaddingLeft) * 2) < $MaxLength+TABLEWIDTH);
my $Counter = 0;
$PaddingLeft .= ' ' if (length($Heading{$Type}) + (length($PaddingLeft) * 2) +2 < $MaxLength+TABLEWIDTH);
print $LeadIn{$Type};
# print table header
print &Divider('=',$MaxLength);
printf(": %s%s%s :\n",$PaddingLeft,$Heading{$Type},$PaddingRight);
print &Divider('=',$MaxLength);
@ -163,11 +232,26 @@ printf(": %-3s : %-6s : %-7s : %-*s :\n",
$MaxLength,$TH{'name'});
print &Divider('-',$MaxLength);
foreach my $Name (sort { $Value{$b} <=> $Value {$a}} keys %Value) {
# print table
my $Counter = 0;
foreach my $Name (sort { $Value{$b} <=> $Value{$a} } keys %Value) {
$Counter++;
printf(": %3u. : %6u : %6.2f%% : %-*s :\n",$Counter,$Value{$Name},&Percentage($SumTotal,$Value{$Name}),$MaxLength,$Name);
printf(": %3u. : %6u : %6.2f%% : %-*s :\n",
$Counter,$Value{$Name},&Percentage($SumTotal,$Value{$Name}),
$MaxLength,$Name);
# handle client versions
if ($SubValue{$Name}) {
foreach my $SubName (sort { $SubValue{$Name}{$b} <=> $SubValue{$Name}{$a} }
keys %{$SubValue{$Name}}) {
printf(": : %6u : %6.2f%% : %-*s :\n",
$SubValue{$Name}{$SubName},
&Percentage($SumTotal,$SubValue{$Name}{$SubName}),
$MaxLength,$SubName);
}
}
}
# print table footer
print &Divider('-',$MaxLength);
printf(": : %6u : %s : %-*s :\n",$SumTotal,'100.00%',$MaxLength,'');
print &Divider('=',$MaxLength);
@ -184,7 +268,7 @@ postingstats - format and post reports
=head1 SYNOPSIS
B<postingstats> B<-t> I<groups|hosts> [B<-Vh> [B<-m> I<YYYY-MM>]
B<postingstats> B<-t> I<groups|hosts|clients> [B<-Vh> [B<-m> I<YYYY-MM>]
=head1 REQUIREMENTS
@ -193,8 +277,8 @@ See L<doc/README>.
=head1 DESCRIPTION
This script will re-format reports on newsgroup usage created by
B<groupstats.pl> or B<hoststats.pl> and create a message that can
be posted to Usenet.
B<groupstats.pl>, B<hoststats.pl> or B<clientstats.pl> and create a
message that can be posted to Usenet.
=head2 Features and options
@ -228,8 +312,8 @@ sum total.
=item C<%Heading>
Hash with keys for I<GroupStats> and I<HostStats>. Used to display a
heading.
Hash with keys for I<GroupStats>, I<HostStats> and I<ClientStats>.
Used to display a heading.
=item C<%TH>
@ -242,14 +326,14 @@ Output will be truncated otherwise.
=item C<%LeadIn>
Hash with keys for I<GroupStats> and I<HostStats>. Used to create the
headers for our posting. Can contain other text that will be shown
before C<%Heading>.
Hash with keys for I<GroupStats>, I<HostStats> and I<ClientStats>.
Used to create the headers for our posting. Can contain other text
that will be shown before C<%Heading>.
=item C<%LeadOut>
Hash with keys for I<GroupStats> and I<HostStats>. Will be shown at the
end of our posting.
Hash with keys for I<GroupStats>, I<HostStats> and I<ClientStats>.
Will be shown at the end of our posting.
=back
@ -265,9 +349,10 @@ Print out version and copyright information and exit.
Print this man page and exit.
=item B<-t>, B<--type> I<groups|hosts>
=item B<-t>, B<--type> I<groups|hosts|clients>
Set report type to posting statistics or hosts statistics accordingly.
Set report type to posting statistics, hosts statistics or client
statistics accordingly.
=item B<-m>, B<--month> I<YYYY-MM>
@ -293,6 +378,10 @@ Create a posting from a host statistics report for last month:
hoststats.pl --nocomments --sums --format dump | postingstats.pl -t hosts
Create a posting from a client statistics report for last month:
clientstats.pl --nocomments --sums --versions --format dump | postingstats.pl -t clients
=head1 FILES
=over 4
@ -336,6 +425,10 @@ groupstats -h
hoststats -h
=item -
clientstats -h
=back
This script is part of the B<NewsStats> package.

View file

@ -7,6 +7,7 @@ NewsStats 0.4.0 (unreleased)
* Add ClientStats to gatherstats.
* Move cliservstats to hoststats.
* Add clientstats (for clients).
* Add ClientStats to postingstats.
NewsStats 0.3.0 (2025-05-18)
* Extract GroupStats (in gatherstats) to subroutine.