--- /dev/null
+
+package Debbugs::User;
+
+=head1 NAME
+
+Debbugs::User -- User settings
+
+=head1 SYNOPSIS
+
+use Debbugs::User qw(is_valid_user read_usertags write_usertags);
+
+read_usertags(\%ut, $userid);
+write_usertags(\%ut, $userid);
+
+=head1 EXPORT TAGS
+
+=over
+
+=item :all -- all functions that can be exported
+
+=back
+
+=head1 FUNCTIONS
+
+=cut
+
+use warnings;
+use strict;
+use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
+use base qw(Exporter);
+
+BEGIN {
+ ($VERSION) = q$Revision: 1.1 $ =~ /^Revision:\s+([^\s+])/;
+ $DEBUG = 0 unless defined $DEBUG;
+
+ @EXPORT = ();
+ @EXPORT_OK = qw(is_valid_user read_usertags write_usertags);
+ $EXPORT_TAGS{all} = [@EXPORT_OK];
+}
+
+
+my $gSpoolPath = "/org/bugs.debian.org/spool";
+
+sub esc {
+ my $s = shift;
+ if ($s =~ m/^[0-9a-zA-Z_+.-]$/) { return $s; }
+ else { return sprintf("%%%02X", ord($s)); }
+}
+
+sub filefromemail {
+ my $e = shift;
+ my $l = length($e) % 7;
+ return "$gSpoolPath/user/$l/" . join("", map { esc($_); } split //, $e);
+}
+
+sub read_stanza {
+ my $f = shift;
+ my $field = 0;
+ my @res;
+ while (<$f>) {
+ chomp;
+ last if (m/^$/);
+
+ if ($field && m/^ (.*)$/) {
+ $res[-1] .= "\n" . $1;
+ } elsif (m/^([^:]+):\s+(.*)$/) {
+ $field = $1;
+ push @res, ($1, $2);
+ }
+ }
+ return @res;
+}
+
+sub read_usertags {
+ my $ut = shift;
+ my $u = shift;
+ my $p = filefromemail($u);
+ my $uf;
+
+ open($uf, "< $p") or return;
+ while(1) {
+ my @stanza = read_stanza($uf);
+ last if ($#stanza == -1);
+ if ($stanza[0] eq "Tag") {
+ my %tag = @stanza;
+ my $t = $tag{"Tag"};
+ $ut->{$t} = [] unless defined $ut->{$t};
+ push @{$ut->{$t}}, split /\s*,\s*/, $tag{Bugs};
+ }
+ }
+ close($uf);
+}
+
+sub fmt {
+ my $s = shift;
+ my $n = shift;
+ my $sofar = 0;
+ my $res = "";
+ while ($s =~ m/^([^,]*,\s*)(.*)$/ || $s =~ m/^([^,]+)()$/) {
+ my $k = $1;
+ $s = $2;
+ unless ($sofar == 0 or $sofar + length($k) <= $n) {
+ $res .= "\n ";
+ $sofar = 1;
+ }
+ $res .= $k;
+ $sofar += length($k);
+ }
+ return $res . $s;
+}
+
+sub write_usertags {
+ my $ut = shift;
+ my $u = shift;
+ my $p = filefromemail($u);
+
+ open(U, "> $p") or die "couldn't write to $p";
+ for my $t (keys %{$ut}) {
+ next if @{$ut->{$t}} == 0;
+ print U "Tag: $t\n";
+ print U fmt("Bugs: " . join(", ", @{$ut->{$t}}), 77) . "\n";
+ print U "\n";
+ }
+ close(U);
+}
+
+sub is_valid_user {
+ my $u = shift;
+ return ($u =~ /^[a-zA-Z0-9._+-]+[@][a-z0-9-.]{4,}$/);
+}
+
+
+1;
+
+__END__
$MLDBM::RemoveTaint = 1;
+my %common_bugusertags;
my $common_mindays = 0;
my $common_maxdays = -1;
my $common_archive = 0;
if ($opt eq "arch") { $common_arch = $val; }
if ($opt eq "maxdays") { $common_maxdays = $val; }
if ($opt eq "mindays") { $common_mindays = $val; }
+ if ($opt eq "bugusertags") { %common_bugusertags = %{$val}; }
}
sub readparse {
%status = %{ readbug( $bugnum, $location ) };
$status{ id } = $bugnum;
+
+ if (defined $common_bugusertags{$bugnum}) {
+ $status{keywords} = "" unless defined $status{keywords};
+ $status{keywords} .= " " unless $status{keywords} eq "";
+ $status{keywords} .= join(" ", @{$common_bugusertags{$bugnum}});
+ }
$status{tags} = $status{keywords};
my %tags = map { $_ => 1 } split ' ', $status{tags};
require '/etc/debbugs/config';
require '/etc/debbugs/text';
+use Debbugs::User;
+
use vars qw($gPackagePages $gWebDomain);
if (defined $ENV{REQUEST_METHOD} and $ENV{REQUEST_METHOD} eq 'HEAD') {
my $show_list_header = ($param{'show_list_header'} || $userAgent->{'show_list_header'} || "yes" ) eq "yes";
my $show_list_footer = ($param{'show_list_footer'} || $userAgent->{'show_list_footer'} || "yes" ) eq "yes";
+my $users = $param{'users'} || "";
+my %bugusertags;
+my %ut;
+for my $user (split /\s*,\s*/, $users) {
+ Debbugs::User::read_usertags(\%ut, $user);
+}
+for my $t (keys %ut) {
+ for my $b (@{$ut{$t}}) {
+ $bugusertags{$b} = [] unless defined $bugusertags{$b};
+ push @{$bugusertags{$b}}, $t;
+ }
+}
+
{
if (defined $param{'vt'}) {
my $vt = $param{'vt'};
set_option("use-bug-idx", defined($param{'use-bug-idx'}) ? $param{'use-bug-idx'} : 0);
set_option("show_list_header", $show_list_header);
set_option("show_list_footer", $show_list_footer);
+set_option("bugusertags", \%bugusertags);
my $title;
my @bugs;
$title = "bugs tagged $tag";
$title .= " in $dist" if defined $dist;
my @tags = split /,/, $tag;
+ my %bugs = ();
+ for my $t (@tags) {
+ for my $b (@{$ut{$t}}) {
+ $bugs{$b} = 1;
+ }
+ }
@bugs = @{getbugs(sub {my %d = @_;
+ return 1 if $bugs{$d{"bug"}};
my %tags = map { $_ => 1 } split ' ', $d{"tags"};
return grep(exists $tags{$_}, @tags);
})};
# -*- perl -*-
-# $Id: errorlib.in,v 1.50 2005/10/06 03:32:13 ajt Exp $
+# $Id: errorlib.in,v 1.51 2005/10/06 03:40:32 ajt Exp $
use Mail::Address;
use Debbugs::MIME qw(decode_rfc1522 encode_rfc1522);
#!/usr/bin/perl
-# $Id: process.in,v 1.104 2005/10/06 03:32:13 ajt Exp $
+# $Id: process.in,v 1.105 2005/10/06 03:40:32 ajt Exp $
#
# Usage: process nn
# Temps: incoming/Pnn
#!/usr/bin/perl
-# $Id: processall.in,v 1.11 2005/10/06 03:32:13 ajt Exp $
+# $Id: processall.in,v 1.12 2005/10/06 03:40:32 ajt Exp $
#
# Usage: processall
#
#!/usr/bin/perl
-# $Id: service.in,v 1.113 2005/10/06 03:32:13 ajt Exp $
+# $Id: service.in,v 1.114 2005/10/06 03:40:32 ajt Exp $
#
# Usage: service <code>.nn
# Temps: incoming/P<code>.nn
use MIME::Parser;
use Debbugs::MIME qw(decode_rfc1522 encode_rfc1522);
use Debbugs::Mail qw(send_mail_message);
+use Debbugs::User;
$config_path = '/etc/debbugs';
$lib_path = '/usr/lib/debbugs';
$midix=0;
$extras="";
+my $user = $replyto;
+$user =~ s/,.*//;
+$user =~ s/^.*<(.*)>.*$/$1/;
+$user =~ s/[(].*[)]//;
+$user =~ s/^\s*(\S+)\s+.*$/$1/;
+$user = "" unless (Debbugs::User::is_valid_user($user));
+
my $quickabort = 0;
my $fuckheads = "(" . join("|", @gFuckheads) . ")";
soon: UNSUBSCRIBE_TEXT
soon: MAILINGLISTS_TEXT
END
+ } elsif (m/^user\s+(\S+)\s*$/i) {
+ my $newuser = $1;
+ if (Debbugs::User::is_valid_user($newuser)) {
+ my $olduser = ($user ne "" ? " (was $user)" : "");
+ &transcript("Setting user to $newuser$olduser.\n");
+ $user = $newuser;
+ } else {
+ &transcript("Selected user id ($newuser) invalid, sorry\n");
+ $user = "";
+ }
+ } elsif (m/^usertags?\s+\#?(-?\d+)\s+(([=+-])\s*)?(\S.*)?$/i) {
+ $ok++;
+ $ref = $1; $addsubcode = $3 || "+"; $tags = $4;
+ if ($user eq "") {
+ &transcript("No valid user selected\n");
+ } else {
+ my %ut;
+ Debbugs::User::read_usertags(\%ut, $user);
+ my @oldtags = (); my @newtags = ();
+ my %chtags = map { ($_, 1) } split /[,\s]+/, $tags;
+ for my $t (keys %chtags) {
+ $ut{$t} = [] unless defined $ut{$t};
+ }
+ for my $t (keys %ut) {
+ my %res = map { ($_, 1) } @{$ut{$t}};
+ push @oldtags, $t if defined $res{$ref};
+ my $addop = ($addsubcode eq "+" or $addsubcode eq "=");
+ my $del = (defined $chtags{$t} ? $addsubcode eq "-"
+ : $addsubcode eq "=");
+ $res{$ref} = 1 if ($addop && defined $chtags{$t});
+ delete $res{$ref} if ($del);
+ push @newtags, $t if defined $res{$ref};
+ $ut{$t} = [ sort { $a <=> $b } (keys %res) ];
+ }
+ if (@oldtags == 0) {
+ &transcript("There were no usertags set.\n");
+ } else {
+ &transcript("Usertags were: " . join(" ", @oldtags) . ".\n");
+ }
+ &transcript("Usertags are now: " . join(" ", @newtags) . ".\n");
+ Debbugs::User::write_usertags(\%ut, $user);
+ }
} elsif (!$control) {
&transcript(<<END);
Unknown command or malformed arguments to command.
&transcript("Too many unknown commands, stopping here.\n\n");
last;
}
-#### interesting ones start here
+#### "developer only" ones start here
} elsif (m/^close\s+\#?(-?\d+)(?:\s+(\d.*))?$/i) {
$ok++;
$ref= $1;