#!/usr/bin/env python
# Utility functions for katie
-# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: katie.py,v 1.27 2002-10-16 02:47:32 troup Exp $
+# Copyright (C) 2001, 2002, 2003 James Troup <james@nocrew.org>
+# $Id: katie.py,v 1.36 2003-07-29 14:57:03 ajt Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
else:
Subst["__STABLE_WARNING__"] = "";
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.bug-close");
- utils.send_mail (mail_message, "");
+ utils.send_mail (mail_message);
if action:
self.Logger.log(["closing bugs"]+bugs);
else: # NMU
if action and control_message != "":
Subst["__CONTROL_MESSAGE__"] = control_message;
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.bug-nmu-fixed");
- utils.send_mail (mail_message, "");
+ utils.send_mail (mail_message);
if action:
self.Logger.log(["setting bugs to fixed"]+bugs);
summary += "\n";
if Cnf.get("Dinstall::TrackingServer") and changes["architecture"].has_key("source"):
Subst["__ANNOUNCE_LIST_ADDRESS__"] = Subst["__ANNOUNCE_LIST_ADDRESS__"] + "\nBcc: %s@%s" % (changes["source"], Cnf["Dinstall::TrackingServer"]);
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.announce");
- utils.send_mail (mail_message, "");
+ utils.send_mail (mail_message);
if Cnf.FindB("Dinstall::CloseBugs"):
summary = self.close_bugs(summary, action);
Subst["__SUITE__"] = "";
Subst["__SUMMARY__"] = summary;
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.accepted");
- utils.send_mail(mail_message, "")
+ utils.send_mail(mail_message)
self.announce(short_summary, 1)
# Special support to enable clean auto-building of accepted packages
# Ignore this; it's a common mistake and not worth whining about
if section.lower() == "non-us/main" and override_section.lower() == "non-us":
continue;
- summary += "%s: section is overridden from %s to %s.\n" % (file, section, override_section);
+ summary += "%s: package says section is %s, override says %s.\n" % (file, section, override_section);
priority = files[file]["priority"];
override_priority = files[file]["override priority"];
if priority != override_priority and priority != "-":
- summary += "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority);
+ summary += "%s: package says priority is %s, override says %s.\n" % (file, priority, override_priority);
if summary == "":
return;
Subst["__SUMMARY__"] = summary;
mail_message = utils.TemplateSubst(Subst,self.Cnf["Dir::Templates"]+"/jennifer.override-disparity");
- utils.send_mail (mail_message, "");
+ utils.send_mail(mail_message);
###########################################################################
- def force_move (self, files):
- """Forcefully move files from the current directory to the reject
- directory. If any file already exists it will be moved to the
- morgue to make way for the new file."""
+ def force_reject (self, files):
+ """Forcefully move files from the current directory to the
+ reject directory. If any file already exists in the reject
+ directory it will be moved to the morgue to make way for
+ the new file."""
Cnf = self.Cnf
while answer == 'E':
os.system("%s %s" % (editor, temp_filename))
file = utils.open_file(temp_filename);
- reject_message = " ".join(file.readlines());
+ reject_message = "".join(file.readlines());
file.close();
print "Reject message:";
- print utils.prefix_multi_line_string(reject_message," ");
+ print utils.prefix_multi_line_string(reject_message," ",include_blank_lines=1);
prompt = "[R]eject, Edit, Abandon, Quit ?"
answer = "XXX";
while prompt.find(answer) == -1:
# Move all the files into the reject directory
reject_files = pkg.files.keys() + [pkg.changes_file];
- self.force_move(reject_files);
+ self.force_reject(reject_files);
# If we fail here someone is probably trying to exploit the race
# so let's just raise an exception ...
# Send the rejection mail if appropriate
if not Cnf["Dinstall::Options::No-Mail"]:
- utils.send_mail (reject_mail_message, "");
+ utils.send_mail(reject_mail_message);
self.Logger.log(["rejected", pkg.changes_file]);
return 0;
# (2) Bin-only NMU of an MU => 1.0-3.0.1
# (3) Bin-only NMU of a sourceful-NMU => 1.0-3.1.1
- def source_exists (self, package, source_version):
- q = self.projectB.query("SELECT s.version FROM source s WHERE s.source = '%s'" % (package));
-
- # Reduce the query results to a list of version numbers
- ql = map(lambda x: x[0], q.getresult());
-
- # Try (1)
- if ql.count(source_version):
- return 1;
-
- # Try (2)
- orig_source_version = re_bin_only_nmu_of_mu.sub('', source_version);
- if ql.count(orig_source_version):
- return 1;
-
- # Try (3)
- orig_source_version = re_bin_only_nmu_of_nmu.sub('', source_version);
- if ql.count(orig_source_version):
- return 1;
-
- # No source found...
- return 0;
+ def source_exists (self, package, source_version, suites = ["any"]):
+ okay = 1
+ for suite in suites:
+ if suite == "any":
+ que = "SELECT s.version FROM source s WHERE s.source = '%s'" % \
+ (package)
+ else:
+ suite_id = db_access.get_suite_id(suite);
+ que = "SELECT s.version FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE sa.suite = %d AND s.source = '%s'" % (suite_id, package)
+ q = self.projectB.query(que)
+
+ # Reduce the query results to a list of version numbers
+ ql = map(lambda x: x[0], q.getresult());
+
+ # Try (1)
+ if ql.count(source_version):
+ continue
+
+ # Try (2)
+ orig_source_version = re_bin_only_nmu_of_mu.sub('', source_version)
+ if ql.count(orig_source_version):
+ continue
+
+ # Try (3)
+ orig_source_version = re_bin_only_nmu_of_nmu.sub('', source_version)
+ if ql.count(orig_source_version):
+ continue
+
+ # No source found...
+ okay = 0
+ return okay
################################################################################
################################################################################
+ # **WARNING**
+ # NB: this function can remove entries from the 'files' index [if
+ # the .orig.tar.gz is a duplicate of the one in the archive]; if
+ # you're iterating over 'files' and call this function as part of
+ # the loop, be sure to add a check to the top of the loop to
+ # ensure you haven't just tried to derefernece the deleted entry.
+ # **WARNING**
+
def check_dsc_against_db(self, file):
self.reject_message = "";
files = self.pkg.files;
actual_size = int(files[dsc_file]["size"]);
found = "%s in incoming" % (dsc_file)
# Check the file does not already exist in the archive
- q = self.projectB.query("SELECT f.size, f.md5sum FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file));
+ q = self.projectB.query("SELECT size, md5sum, filename FROM files WHERE filename LIKE '%%%s%%'" % (dsc_file));
- # "It has not broken them. It has fixed a
+ ql = q.getresult();
+ # Strip out anything that isn't '%s' or '/%s$'
+ for i in ql:
+ if i[2] != dsc_file and i[2][-(len(dsc_file)+1):] != '/'+dsc_file:
+ self.Logger.log(["check_dsc_against_db",i[2],dsc_file]);
+ ql.remove(i);
+
+ # "[katie] has not broken them. [katie] has fixed a
# brokenness. Your crappy hack exploited a bug in
# the old dinstall.
#
# the same name and version.)"
# -- ajk@ on d-devel@l.d.o
- ql = q.getresult();
if ql:
# Ignore exact matches for .orig.tar.gz
match = 0;
self.reject("can not overwrite existing copy of '%s' already in the archive." % (dsc_file));
elif dsc_file.endswith(".orig.tar.gz"):
# Check in the pool
- q = self.projectB.query("SELECT l.path, f.filename, l.type, f.id, l.id FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file));
+ q = self.projectB.query("SELECT l.path, f.filename, l.type, f.id, l.id FROM files f, location l WHERE f.filename LIKE '%%%s%%' AND l.id = f.location" % (dsc_file));
ql = q.getresult();
+ # Strip out anything that isn't '%s' or '/%s$'
+ for i in ql:
+ if i[1] != dsc_file and i[1][-(len(dsc_file)+1):] != '/'+dsc_file:
+ self.Logger.log(["check_dsc_against_db",i[1],dsc_file]);
+ ql.remove(i);
if ql:
# Unfortunately, we make get more than one