Ticket #25: mkngfile

File mkngfile, 4.5 KB (added by eagle, 14 years ago)

mkngfile from Jeremy Nixon

Line 
1#!/usr/local/bin/perl
2#
3# mkngfile - make a newsgroup description file from multiple sources
4#
5# Jeremy Nixon <jeremy@exit109.com>
6#  $Id: mkngfile,v 1.1 1999/04/17 09:19:25 jeremy Exp $
7#
8# This program may be used and distributed under the same terms
9# as Perl itself.
10
11# This program creates a newsgroup description file, using one or
12# several input files containing group descriptions.  The resulting
13# file will contain a description line for each group in your active
14# file.
15#
16# If the input contains multiple different descriptions for a group,
17# the program will prompt interactively for which one to use; or, if
18# the --noask option is given, one will be chosen arbitrarily.  If a
19# group has no description, $default_desc (below) will be used.
20#
21# The output will be sent to stdout, or to the file specified with
22# the --output (or -o) option.
23#
24# Example - to run with your existing newsgroups file, a local copy
25# of the ISC newsgroups file, and a directory containing checkgroups
26# files with names like *.check, creating the new file as 'newfile':
27#  mkngfile -o newfile /news/etc/newsgroups newsgroups checkgroups/*.check
28#
29# You can set the location of your active file below so you don't
30# have to specify it on the command line.
31
32use Getopt::Long;
33
34GetOptions (\%opt, qw(h help a=s active=s ask! o=s output=s)) || usage();
35usage() if ($opt{'h'} or $opt{'help'});
36usage('No input files specified.') unless (scalar @ARGV > 0);
37
38# If a group has no description, use this.
39$default_desc = '???';
40
41# Default to asking which of multiple descriptions to use.
42# Comment this out if you want the default to be not to ask.
43$opt{'ask'} = 1 unless (defined $opt{'ask'});
44
45# Default to system active file; you may want to change this.
46$active_file = $opt{'active'} || $opt{'a'} || '/news/etc/active';
47usage('No active file.') unless (-r $active_file);
48
49$output_file = $opt{'output'} || $opt{'o'} || undef;
50
51# Read in the active file and create a hash.
52open (F, "<$active_file") || die "Can't open $active: $!\n";
53%active = map { (split /\s+/, $_)[0,3] } <F>;
54close F;
55
56# Read in all the files and create a hash.
57%groups = ();
58while (defined ($file = shift @ARGV)) {
59
60    unless (open (F, "<$file")) {
61        print STDERR "Can't open $file: $!\n";
62        next;
63    }
64    while (defined ($line = <F>)) {
65        chomp $line;
66        ($group,$desc) = split /\s+/, $line, 2;
67        $desc =~ s/\(Moderated\)//gi;
68        $desc =~ s/^\s+//;
69        $desc =~ s/\s+$//;
70        next if ($desc =~ /^\s*$/ or $desc =~ /^\?+$/ or $desc =~ /no description/i);
71        $groups{$group}{$desc} = 1;
72    }
73    close F;
74}
75
76# Go through the active file and find each group's description.
77@descriptions = ();
78foreach $group (sort keys %active) {
79    $desc = pick_description ($group);
80    push @descriptions, "$group\t$desc";
81}
82
83# If we have an output file, open it; otherwise STDOUT is used.
84if ($output_file) {
85    open (OUT, ">$output_file") or die "Can't open $output_file: $!\n";
86    open (STDOUT, ">&OUT") or die "Can't redirect stdout: $!\n";
87}
88
89# Print the new file.
90map { print "$_\n" } @descriptions;
91
92close OUT if ($output_file);
93
94sub pick_description {
95    # Given a group, return the description.
96    # If we have more than one description for a group, we ask the
97    # user which one to use, or just pick one if --noask is specified.
98    # If we have no description for a group, use $default_desc.
99    # If the group is moderated, append '(Moderated)' to the description.
100
101    my ($description,$n,$c);
102    my $ng = shift;
103    my @descs = sort keys %{$groups{$ng}};
104
105    if (scalar @descs < 1) {
106        $description = $default_desc;
107    } elsif (scalar @descs == 1) {
108        $description = $descs[0];
109    } else {
110        if ($opt{'ask'}) {
111
112            print STDERR "$ng - choose description:\n";
113            map { print STDERR " ". ++$n .". $_\n" } @descs;
114            until ($c > 0 and $c <= scalar @descs) {
115                print STDERR "> ";
116                $c = <STDIN>;
117                chomp $c;
118            }
119            $description = $descs[--$c];
120
121        } else {
122            $description = $descs[0];
123        }
124    }
125    $description .= ' (Moderated)' if ($active{$ng} =~ /^m/i);
126
127    return $description;
128}
129
130sub usage {
131    my $message = shift;
132    print STDERR "$message\n" if ($message);
133
134    print STDERR "\nusage:\n";
135    print STDERR "mkngfile [options] file [file...]\n";
136    print STDERR " -h, --help    display this message\n";
137    print STDERR " -a, --active  path to active file\n";
138    print STDERR " -o, --output  output file to use instead of stdout\n";
139    print STDERR " --ask         ask which of multiple descriptions to use (default)\n";
140    print STDERR " --noask       don't ask, just pick one\n";
141    print STDERR "\n";
142
143    exit 1;
144}