/[collab-qa]/udd/udd/bugs_gatherer.pl
ViewVC logotype

Contents of /udd/udd/bugs_gatherer.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 999 - (show annotations) (download)
Fri Aug 8 13:53:23 2008 UTC (4 years, 9 months ago) by neronus-guest
Original Path: udd/src/udd/bugs_gatherer.pl
File MIME type: text/plain
File size: 8217 byte(s)
Removed surviving 'next' statement
1 #!/usr/bin/perl
2 # Last-Modified: <Fri Aug 8 13:56:31 2008>
3
4 use strict;
5 use warnings;
6
7 use FindBin '$Bin';
8
9 # We need our own copy of Debbugs::Status for now
10 use lib $Bin, qw{/org/udd.debian.net/mirrors/bugs.debian.org/perl};
11
12 use DBI;
13 use YAML::Syck;
14 use Time::Local;
15
16 use Debbugs::Bugs qw{get_bugs};
17 use Debbugs::Status qw{read_bug get_bug_status bug_presence};
18 use Debbugs::Packages qw{binarytosource};
19 use Debbugs::Config qw{:globals};
20 use Debbugs::User qw{read_usertags};
21
22 $YAML::Syck::ImplicitTyping = 1;
23
24 # Return the list of usernames
25 sub get_bugs_users {
26 my $topdir = "$gSpoolDir/user";
27 my @ret = ();
28 # see Debbugs::User::filefromemail for why 0...6
29 for(my $i = 0; $i < 7; $i++) {
30 my $dir = "$topdir/$i";
31 opendir DIR, $dir or die "Can't open dir $dir: $!";
32 # Replace all occurences of %dd with the corresponding
33 # character represented by dd, where dd is a hexadecimal
34 # number
35 push @ret, map { s/%(..)/chr(hex($1))/ge; $_ } readdir DIR;
36 }
37 return @ret;
38 }
39
40 sub parse_time {
41 if(shift =~ /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/) {
42 return ($1, $2, $3, $4, $5, $6);
43 }
44 return undef;
45 }
46
47
48 sub get_db_max_last_modified {
49 my $dbh = shift or die "Argument required";
50 my $sth = $dbh->prepare("SELECT MAX (last_modified) FROM bugs");
51 $sth->execute() or die $!;
52 my $date = $sth->fetchrow_array();
53 if(defined $date) {
54 my ($year, $month, $day, $hour, $minute, $second) = parse_time($date);
55 return timelocal($second, $minute, $hour, $day, $month-1, $year);
56 } else {
57 return 0;
58 }
59 }
60
61 sub get_mtime {
62 return ((stat(shift))[9]);
63 }
64
65 sub get_modified_bugs {
66 my $prune_stamp = shift;
67 die "Argument required" unless defined $prune_stamp;
68 my $top_dir = $gSpoolDir;
69 my @result = ();
70 foreach my $sub (qw(archive db-h)) {
71 my $spool = "$top_dir/$sub";
72 foreach my $subsub (glob "$spool/*") {
73 if( -d $subsub and get_mtime($subsub) > $prune_stamp ) {
74 push @result,
75 map { s{.*/(.*)\.log}{$1}; $_ }
76 grep { get_mtime("$_") > $prune_stamp }
77 glob "$subsub/*.log";
78 }
79 }
80 }
81 return \@result;
82 }
83
84 sub without_duplicates {
85 my %h = ();
86 return (grep { ($h{$_}++ == 0) || 0 } @_);
87 }
88
89 sub main {
90 if(@ARGV != 2) {
91 print STDERR "Usage: $0 <config> <source>";
92 exit 1;
93 }
94
95 my $config = LoadFile($ARGV[0]) or die "Could not load configuration: $!";
96 my $source = $ARGV[1];
97 my %src_config = %{$config->{$source}};
98
99 my $dbname = $config->{general}->{dbname};
100 # Connection to DB
101 my $dbh = DBI->connect("dbi:Pg:dbname=$dbname");
102 # We want to commit the transaction as a hole at the end
103 $dbh->{AutoCommit} = 0;
104
105
106
107 # Free usertags table
108 $dbh->prepare("DELETE FROM bug_user_tags")->execute() or die
109 "Couldn't empty bug_user_tags: $!";
110
111 # read and insert user tags
112 my @users = get_bugs_users();
113 foreach my $user (@users) {
114 my %tags = ();
115 read_usertags(\%tags, $user);
116 $user = $dbh->quote($user);
117 foreach my $tag (keys %tags) {
118 my $qtag = $dbh->quote($tag);
119 map { $dbh->prepare("INSERT INTO bug_user_tags VALUES ($user, $qtag, $_)")->execute() or die $! } @{$tags{$tag}};
120 }
121 }
122
123 ####### XXX EXPERIMENT
124 ####### XXX What to do with bugs both archived and unarchived
125 #my $max_last_modified = get_db_max_last_modified($dbh);
126 #my @modified_bugs;
127 #if($max_last_modified) {
128 # @modified_bugs = @{get_modified_bugs($max_last_modified)};
129 # Delete modified bugs
130 # for my $bug (@modified_bugs) {
131 # map {
132 # $dbh->prepare("DELETE FROM $_ WHERE id = $bug")->execute()
133 # } qw{bugs bug_merged_with bug_found_in bug_fixed_in};
134 # }
135 #} else {
136 # @modified_bugs = get_bugs(archive => 'both');
137 #}
138 #@modified_bugs = without_duplicates(@modified_bugs);
139 my @modified_bugs;
140 if($src_config{archived}) {
141 @modified_bugs = get_bugs(archive => 1);
142 } else {
143 @modified_bugs = get_bugs();
144 }
145
146 print scalar(@modified_bugs), " modified bugs\n";
147 ####### XXX EXPERIMENT
148
149 # Get the bugs we want to import
150 # my @bugs = $src_config{archived} ? get_bugs(archive => 1) : get_bugs();
151
152 # Delete all bugs we are going to import
153 for my $bug (@modified_bugs) {
154 map {
155 $dbh->prepare("DELETE FROM $_ WHERE id = $bug")->execute() or die $!
156 } qw{bugs_archived bugs_unarchived bug_merged_with bug_found_in bug_fixed_in bug_tags};
157 }
158 print "Bugs deleted\n";
159
160 # Used to chache binary to source mappings
161 my %binarytosource = ();
162
163 # XXX What if a bug is in location 'db' (which currently doesn't exist)
164 my $location = $src_config{archived} ? 'archive' : 'db_h';
165 my $table = $src_config{archived} ? 'bugs_archived' : 'bugs_unarchived';
166 # Read all bugs
167 foreach my $bug_nr (@modified_bugs) {
168 # Fetch bug using Debbugs
169 # Bugs which were once archived and have been unarchived again will appear in get_bugs(archive => 1).
170 # However, those bugs are not to be found in location 'archive', so we detect them, and skip them
171 my $bug_ref = read_bug(bug => $bug_nr, location => $location) or (print STDERR "Could not read file for bug $bug_nr; skipping\n" and next);
172 # Yeah, great, why does get_bug_status not accept a location?
173 my %bug = %{get_bug_status(bug => $bug_nr, status => $bug_ref)};
174
175 # Convert data where necessary
176 map { $bug{$_} = $dbh->quote($bug{$_}) } qw(subject originator owner pending);
177 my @found_versions = map { $dbh->quote($_) } @{$bug{found_versions}};
178 my @fixed_versions = map { $dbh->quote($_) } @{$bug{fixed_versions}};
179 my @tags = map {$dbh->quote($_) } split / /, $bug{keywords};
180
181 # log_modified and date are not necessarily set. If they are not available, they
182 # are assumed to be epoch (i.e. bug #4170)
183 map {
184 if($bug{$_}) {
185 $bug{$_} = "$bug{$_}::abstime";
186 } else {
187 $bug{$_} = '0::abstime';
188 }
189 } qw{date log_modified};
190
191
192 if(not exists $binarytosource{$bug{package}}) {
193 $binarytosource{$bug{package}} = (binarytosource($bug{package}))[0];
194 }
195 my $source = $binarytosource{$bug{package}};
196
197 if(not defined $source) {
198 $source = 'NULL';
199 } else {
200 $source = $dbh->quote($source);
201 }
202
203 #Calculate bug presence in distributions
204 my $present_in_stable =
205 bug_presence(bug => $bug_nr, status => \%bug,
206 dist => 'stable');
207 my $present_in_testing =
208 bug_presence(bug => $bug_nr, status => \%bug,
209 dist => 'testing');
210 my $present_in_unstable =
211 bug_presence(bug => $bug_nr, status => \%bug,
212 dist => 'unstable');
213 if(!defined($present_in_stable) or !defined($present_in_unstable) or !defined($present_in_testing)) {
214 print "NUMBER: $bug_nr\n";
215 }
216 if(defined($present_in_stable) and ($present_in_stable eq 'absent' or $present_in_stable eq 'fixed')) {
217 $present_in_stable = 'FALSE';
218 } else {
219 $present_in_stable = 'TRUE';
220 }
221 if(defined($present_in_testing) and ($present_in_testing eq 'absent' or $present_in_testing eq 'fixed')) {
222 $present_in_testing = 'FALSE';
223 } else {
224 $present_in_testing = 'TRUE';
225 }
226 if(defined($present_in_unstable) and ($present_in_unstable eq 'absent' or $present_in_unstable eq 'fixed')) {
227 $present_in_unstable = 'FALSE';
228 } else {
229 $present_in_unstable = 'TRUE';
230 }
231
232
233 # Insert data into bugs table
234 my $query = "INSERT INTO $table VALUES ($bug_nr, '$bug{package}', $source, $bug{date}, \
235 E$bug{pending}, '$bug{severity}', E$bug{originator}, E$bug{owner}, \
236 E$bug{subject}, $bug{log_modified}, $present_in_stable,
237 $present_in_testing, $present_in_unstable)";
238 # Execute insertion
239 my $sth = $dbh->prepare($query);
240 $sth->execute() or die $!;
241
242 # insert data into bug_fixed_in and bug_found_in tables
243 foreach my $version (without_duplicates(@found_versions)) {
244 $query = "INSERT INTO bug_found_in VALUES ($bug_nr, $version)";
245 $dbh->prepare($query)->execute() or die $!;
246 }
247 foreach my $version (without_duplicates(@fixed_versions)) {
248 $query = "INSERT INTO bug_fixed_in VALUES ($bug_nr, $version)";
249 $dbh->prepare($query)->execute() or die $!;
250 }
251 foreach my $mergee (without_duplicates(split / /, $bug{mergedwith})) {
252 $query = "INSERT INTO bug_merged_with VALUES ($bug_nr, $mergee)";
253 $dbh->prepare($query)->execute() or die $!;
254 }
255 foreach my $tag (without_duplicates(@tags)) {
256 $query = "INSERT INTO bug_tags VALUES ($bug_nr, $tag)";
257 $dbh->prepare($query)->execute() or die $!;
258 }
259 }
260
261 $dbh->commit();
262 }
263
264 main();

  ViewVC Help
Powered by ViewVC 1.1.5