]> pere.pagekite.me Git - homepage.git/blob - linux/gmanespam
Implement more.
[homepage.git] / linux / gmanespam
1 #!/usr/bin/perl
2 #
3 # Author: Petter Reinholdtsen
4 # Date: 2005-12-28
5 # License: GNU Public License v2 or later
6 #
7 # Make it easier to report gmane messages as spam. List all new
8 # messages in a given group, and let the user mark a message as spam
9 # with a single keypress.
10 #
11 # Configuration is in ~/.gmanespam, with content like this:
12 # server news.gmane.org
13 # group gmane.linux.debian.devel.initscripts-ng
14 # group gmane.linux.debian.devel.java
15 #
16 # New version of this script is available from
17 # <URL:http://www.student.uit.no/~pere/linux/>
18
19 use warnings;
20 use strict;
21
22 use Net::NNTP;
23 use LWP::UserAgent;
24
25 my $server = "news.gmane.org";
26
27 # List of groups to process
28 my @groups;
29
30 # Msgnum of the last visited article in the key group.
31 my %grouplast;
32
33 my @configfiles = ("/etc/gmanespam", $ENV{HOME}."/.gmanespam");
34 my $statusfile = $ENV{HOME}."/.gmanespamrc";
35
36 loadconfig();
37
38 my $nntp = Net::NNTP->new($server);
39
40 unless ($nntp) {
41 print "error: Unable to connect to NNTP server '$server'.\n";
42 exit 1;
43 }
44
45 my $ua = LWP::UserAgent->new;
46
47 loadstatus($statusfile);
48
49 for my $group (@groups) {
50 process_gmane_group($group);
51 }
52
53 savestatus($statusfile);
54
55 $nntp->quit;
56
57 sub loadconfig {
58 for my $filename (@configfiles) {
59 open (CFG, "<$filename") || next;
60 while (<CFG>) {
61 chomp;
62 s/\#.*//g;
63 s/\s*$//g;
64 next if (/^$/);
65 $server = $1 if (m/^server (.+)$/);
66 push(@groups, $1) if (m/^group (.+)$/);
67 }
68 close(CFG);
69 }
70 }
71
72 sub loadstatus {
73 my $statusfile = shift;
74 open (STATUS, "<$statusfile");
75 while (<STATUS>) {
76 chomp;
77 my ($groupname, $lastnum) = m/^(\S+): 1-(\d+)$/;
78 $grouplast{$groupname} = $lastnum;
79 }
80 close(STATUS);
81 }
82
83 sub savestatus {
84 my $statusfile = shift;
85 open(STATUS, ">$statusfile") || die "Unable to write to $statusfile";
86 for my $groupname (sort keys %grouplast) {
87 print STATUS "$groupname: 1-".$grouplast{$groupname}."\n";
88 }
89 close(STATUS);
90 }
91
92 sub process_gmane_group {
93 my $group = shift;
94 my ($msgcount, $msgfirst, $msglast, $groupname) = $nntp->group($group);
95 my $curmsgnum = $grouplast{$groupname};
96
97 my @spammsgs;
98
99 print "\n$groupname: $msgfirst -> $msglast ($msgcount)\n";
100 my $aktive = 1;
101 while ($aktive && ++$curmsgnum <= $msglast) {
102 print "\n[$curmsgnum/$msglast] ============ $groupname ===========\n";
103
104 my $headersref = $nntp->head($curmsgnum);
105 unless ($headersref) {
106 print "**** Message does not exist. Skipping.\n";
107 next;
108 }
109 my ($spam, $subject, $from) = process_header($headersref);
110
111 print "From: $from\n";
112 print "Subject: $subject\n";
113 if ($spam) {
114 print "**** Message already flagged as spam. Ignoring.\n";
115 next;
116 }
117 print "Non-spam/Spam/sKip/view Body/view Full/jump #/Help/Quit [N] ? ";
118 my $input = <>;
119 chomp $input;
120 $input = "\L$input";
121 if ("" eq $input || "n" eq $input) {
122 # Not spam, ignore
123 } elsif ("s" eq $input) {
124 # Report as spam
125 push(@spammsgs, $curmsgnum);
126 } elsif ("q" eq $input) {
127 print "Exiting\n";
128 savestatus($statusfile);
129 exit 0;
130 } elsif ($input =~ m/^(\d+)$/) {
131 $curmsgnum = $1 - 1;
132 $curmsgnum = $msglast if $curmsgnum > $msglast;
133 print "Jumping to message number $1\n";
134 next;
135 } elsif ("k" eq $input) {
136 # Skip this group and move to the next group
137 $aktive = 0;
138 } elsif ("f" eq $input) {
139 # View message header and body
140 my $articleref = $nntp->article($curmsgnum);
141 list_lines($articleref);
142 $curmsgnum--;
143 } elsif ("b" eq $input) {
144 # View message body
145 my $bodyref = $nntp->body($curmsgnum);
146 list_lines($bodyref);
147 $curmsgnum--;
148 } elsif ("h" eq $input) {
149 # print help
150 } else {
151 print STDERR "error: Unhandled choice '$input'\n";
152 }
153 }
154 if (@spammsgs) {
155 print "Submit changes? [yes] ";
156 my $input = <>;
157 chomp $input;
158 $input = "\L$input";
159 if ("" eq $input || "yes" eq $input) {
160 for my $msgnum (@spammsgs) {
161 report_spam($groupname, $msgnum);
162 }
163 }
164 }
165 $grouplast{$groupname} = --$curmsgnum;
166 print "Storing $curmsgnum as last read message in $groupname\n";
167 }
168
169 sub list_lines {
170 my $arrayref = shift;
171 for (@{$arrayref}) {
172 print " ", $_;
173 }
174 }
175
176 sub process_header {
177 my $headerref = shift;
178 my $subject;
179 my $from;
180 my $spam;
181 for (@{$headerref}) {
182 $from = $1 if m/^From: (.*)$/i;
183 $subject = $1 if m/^Subject: (.*)$/i;
184 $spam = 1 if m/Xref: .*gmane.spam.detected.*$/;
185 }
186 return ($spam, $subject, $from)
187 }
188
189 sub report_spam {
190 my ($groupname, $msgnum) = @_;
191 # Visit http://spam.gmane.org/gmane.linux.debian.devel.lsb:253
192 my $response = $ua->get("http://spam.gmane.org/$groupname:$msgnum");
193 if ($response->is_success) {
194 print "Reported $groupname:$msgnum as spam.\n";
195 } else {
196 die $response->status_line;
197 }
198 }