]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/queue.py
Remove unused unaccept
[dak.git] / daklib / queue.py
index 5b287172d5d2669b7a112eb89cd60862da2bdb0e..a4914aa3c5b800614db81eb52b7122c097eb3b6f 100755 (executable)
@@ -6,7 +6,7 @@ Queue utility functions for dak
 
 @contact: Debian FTP Master <ftpmaster@debian.org>
 @copyright: 2001 - 2006 James Troup <james@nocrew.org>
-@copyright: 2009  Joerg Jaspert <joerg@debian.org>
+@copyright: 2009, 2010  Joerg Jaspert <joerg@debian.org>
 @license: GNU General Public License version 2 or later
 """
 
@@ -78,6 +78,7 @@ def get_type(f, session):
     elif re_source_ext.match(f["type"]):
         file_type = "dsc"
     else:
+        file_type = f["type"]
         utils.fubar("invalid type (%s) for new.  Dazed, confused and sure as heck not continuing." % (file_type))
 
     # Validate the override type
@@ -91,7 +92,7 @@ def get_type(f, session):
 
 # Determine what parts in a .changes are NEW
 
-def determine_new(changes, files, warn=1):
+def determine_new(changes, files, warn=1, session = None):
     """
     Determine what parts in a C{changes} file are NEW.
 
@@ -110,8 +111,6 @@ def determine_new(changes, files, warn=1):
     """
     new = {}
 
-    session = DBConn().session()
-
     # Build up a list of potentially new things
     for name, f in files.items():
         # Skip byhand elements
@@ -181,13 +180,11 @@ def determine_new(changes, files, warn=1):
             if new[pkg].has_key("othercomponents"):
                 print "WARNING: %s already present in %s distribution." % (pkg, new[pkg]["othercomponents"])
 
-    session.close()
-
     return new
 
 ################################################################################
 
-def check_valid(new):
+def check_valid(new, session = None):
     """
     Check if section and priority for NEW packages exist in database.
     Additionally does sanity checks:
@@ -204,13 +201,13 @@ def check_valid(new):
         priority_name = new[pkg]["priority"]
         file_type = new[pkg]["type"]
 
-        section = get_section(section_name)
+        section = get_section(section_name, session)
         if section is None:
             new[pkg]["section id"] = -1
         else:
             new[pkg]["section id"] = section.section_id
 
-        priority = get_priority(priority_name)
+        priority = get_priority(priority_name, session)
         if priority is None:
             new[pkg]["priority id"] = -1
         else:
@@ -231,17 +228,6 @@ def check_valid(new):
 
 ###############################################################################
 
-def check_status(files):
-    new = byhand = 0
-    for f in files.keys():
-        if files[f].has_key("byhand"):
-            byhand = 1
-        elif files[f].has_key("new"):
-            new = 1
-    return (new, byhand)
-
-###############################################################################
-
 # Used by Upload.check_timestamps
 class TarTime(object):
     def __init__(self, future_cutoff, past_cutoff):
@@ -343,8 +329,18 @@ class Upload(object):
             self.Subst["__MAINTAINER_TO__"] = self.pkg.changes["maintainer2047"]
             self.Subst["__MAINTAINER__"] = self.pkg.changes.get("maintainer", "Unknown")
 
-        if "sponsoremail" in self.pkg.changes:
-            self.Subst["__MAINTAINER_TO__"] += ", %s" % self.pkg.changes["sponsoremail"]
+        # Process policy doesn't set the fingerprint field and I don't want to make it
+        # do it for now as I don't want to have to deal with the case where we accepted
+        # the package into PU-NEW, but the fingerprint has gone away from the keyring in
+        # the meantime so the package will be remarked as rejectable.  Urgh.
+        # TODO: Fix this properly
+        if self.pkg.changes.has_key('fingerprint'):
+            session = DBConn().session()
+            fpr = get_fingerprint(self.pkg.changes['fingerprint'], session)
+            if self.check_if_upload_is_sponsored("%s@debian.org" % fpr.uid.uid, fpr.uid.name):
+                if self.pkg.changes.has_key("sponsoremail"):
+                    self.Subst["__MAINTAINER_TO__"] += ", %s" % self.pkg.changes["sponsoremail"]
+            session.close()
 
         if cnf.has_key("Dinstall::TrackingServer") and self.pkg.changes.has_key("source"):
             self.Subst["__MAINTAINER_TO__"] += "\nBcc: %s@%s" % (self.pkg.changes["source"], cnf["Dinstall::TrackingServer"])
@@ -357,12 +353,19 @@ class Upload(object):
         self.Subst["__REJECT_MESSAGE__"] = self.package_info()
         self.Subst["__SOURCE__"] = self.pkg.changes.get("source", "Unknown")
         self.Subst["__VERSION__"] = self.pkg.changes.get("version", "Unknown")
+        self.Subst["__SUITE__"] = self.pkg.changes.get("distribution", "Unknown")
 
     ###########################################################################
     def load_changes(self, filename):
         """
+        Load a changes file and setup a dictionary around it. Also checks for mandantory
+        fields  within.
+
+        @type filename: string
+        @param filename: Changes filename, full path.
+
         @rtype: boolean
-        @rvalue: whether the changes file was valid or not.  We may want to
+        @return: whether the changes file was valid or not.  We may want to
                  reject even if this is True (see what gets put in self.rejects).
                  This is simply to prevent us even trying things later which will
                  fail because we couldn't properly parse the file.
@@ -459,7 +462,7 @@ class Upload(object):
 
         # Check the .changes is non-empty
         if not self.pkg.files:
-            self.rejects.append("%s: nothing to do (Files field is empty)." % (base_filename))
+            self.rejects.append("%s: nothing to do (Files field is empty)." % (os.path.basename(self.pkg.changes_file)))
             return False
 
         # Changes was syntactically valid even if we'll reject
@@ -574,8 +577,8 @@ class Upload(object):
         architecture = control.Find("Architecture")
         upload_suite = self.pkg.changes["distribution"].keys()[0]
 
-        if      architecture not in [a.arch_string for a in get_suite_architectures(default_suite, session)] \
-            and architecture not in [a.arch_string for a in get_suite_architectures(upload_suite, session)]:
+        if      architecture not in [a.arch_string for a in get_suite_architectures(default_suite, session = session)] \
+            and architecture not in [a.arch_string for a in get_suite_architectures(upload_suite, session = session)]:
             self.rejects.append("Unknown architecture '%s'." % (architecture))
 
         # Ensure the architecture of the .deb is one of the ones
@@ -679,7 +682,7 @@ class Upload(object):
                     entry["new"] = 1
                 else:
                     dsc_file_exists = False
-                    for myq in ["Embargoed", "Unembargoed", "ProposedUpdates", "OldProposedUpdates"]:
+                    for myq in ["Embargoed", "Unembargoed", "ProposedUpdates", "OldProposedUpdates", "Lenny-Volatile-Proposed-Updates"]:
                         if cnf.has_key("Dir::Queue::%s" % (myq)):
                             if os.path.exists(os.path.join(cnf["Dir::Queue::" + myq], dsc_filename)):
                                 dsc_file_exists = True
@@ -784,7 +787,7 @@ class Upload(object):
         location = cnf["Dir::Pool"]
         l = get_location(location, entry["component"], session=session)
         if l is None:
-            self.rejects.append("[INTERNAL ERROR] couldn't determine location (Component: %)" % entry["component"])
+            self.rejects.append("[INTERNAL ERROR] couldn't determine location (Component: %s)" % entry["component"])
             entry["location id"] = -1
         else:
             entry["location id"] = l.location_id
@@ -934,7 +937,7 @@ class Upload(object):
 
         # Parse the .dsc file
         try:
-            self.pkg.dsc.update(utils.parse_changes(dsc_filename, signing_rules=1))
+            self.pkg.dsc.update(utils.parse_changes(dsc_filename, signing_rules=1, dsc_file=1))
         except CantOpenError:
             # if not -n copy_to_holding() will have done this for us...
             if not action:
@@ -1230,7 +1233,7 @@ class Upload(object):
             found = False
 
             # Look in the pool
-            for poolfile in get_poolfile_like_name('/%s' % filename, session_):
+            for poolfile in get_poolfile_like_name('%s' % filename, session_):
                 poolfile_path = os.path.join(
                     poolfile.location.path, poolfile.filename
                 )
@@ -1904,6 +1907,9 @@ distribution."""
                     # Make sure that our source object is up-to-date
                     session.expire(source)
 
+        # Add changelog information to the database
+        self.store_changelog()
+
         # Install the files into the pool
         for newfile, entry in self.pkg.files.items():
             destination = os.path.join(cnf["Dir::Pool"], entry["pool name"], newfile)
@@ -1933,7 +1939,6 @@ distribution."""
             UrgencyLog().log(self.pkg.dsc["source"], self.pkg.dsc["version"], self.pkg.changes["urgency"])
 
         self.update_subst()
-        self.Subst["__SUITE__"] = ""
         self.Subst["__SUMMARY__"] = summary
         mail_message = utils.TemplateSubst(self.Subst,
                                            os.path.join(cnf["Dir::Templates"], 'process-unchecked.accepted'))
@@ -2052,8 +2057,8 @@ distribution."""
         directory it will be moved to the morgue to make way for
         the new file.
 
-        @type files: dict
-        @param files: file dictionary
+        @type reject_files: dict
+        @param reject_files: file dictionary
 
         """
 
@@ -2614,45 +2619,6 @@ distribution."""
                 if not self.in_override_p(entry["package"], entry["component"], suite, entry.get("dbtype",""), checkfile, session):
                     self.rejects.append("%s is NEW for %s." % (checkfile, suite))
 
-    ################################################################################
-    # This is not really a reject, but an unaccept, but since a) the code for
-    # that is non-trivial (reopen bugs, unannounce etc.), b) this should be
-    # extremely rare, for now we'll go with whining at our admin folks...
-
-    def do_unaccept(self):
-        cnf = Config()
-
-        self.update_subst()
-        self.Subst["__REJECTOR_ADDRESS__"] = cnf["Dinstall::MyEmailAddress"]
-        self.Subst["__REJECT_MESSAGE__"] = self.package_info()
-        self.Subst["__CC__"] = "Cc: " + cnf["Dinstall::MyEmailAddress"]
-        self.Subst["__BCC__"] = "X-DAK: dak process-accepted"
-        if cnf.has_key("Dinstall::Bcc"):
-            self.Subst["__BCC__"] += "\nBcc: %s" % (cnf["Dinstall::Bcc"])
-
-        template = os.path.join(cnf["Dir::Templates"], "process-accepted.unaccept")
-
-        reject_mail_message = utils.TemplateSubst(self.Subst, template)
-
-        # Write the rejection email out as the <foo>.reason file
-        reason_filename = os.path.basename(self.pkg.changes_file[:-8]) + ".reason"
-        reject_filename = os.path.join(cnf["Dir::Queue::Reject"], reason_filename)
-
-        # If we fail here someone is probably trying to exploit the race
-        # so let's just raise an exception ...
-        if os.path.exists(reject_filename):
-            os.unlink(reject_filename)
-
-        fd = os.open(reject_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644)
-        os.write(fd, reject_mail_message)
-        os.close(fd)
-
-        utils.send_mail(reject_mail_message)
-
-        del self.Subst["__REJECTOR_ADDRESS__"]
-        del self.Subst["__REJECT_MESSAGE__"]
-        del self.Subst["__CC__"]
-
     ################################################################################
     # If any file of an upload has a recent mtime then chances are good
     # the file is still being uploaded.
@@ -2677,3 +2643,35 @@ distribution."""
 
         os.chdir(cwd)
         return too_new
+
+    def store_changelog(self):
+
+        # Skip binary-only upload if it is not a bin-NMU
+        if not self.pkg.changes['architecture'].has_key('source'):
+            from daklib.regexes import re_bin_only_nmu
+            if not re_bin_only_nmu.search(self.pkg.changes['version']):
+                return
+
+        session = DBConn().session()
+
+        # Check if upload already has a changelog entry
+        query = """SELECT changelog_id FROM changes WHERE source = :source
+                   AND version = :version AND architecture = :architecture AND changelog_id != 0"""
+        if session.execute(query, {'source': self.pkg.changes['source'], \
+                                   'version': self.pkg.changes['version'], \
+                                   'architecture': " ".join(self.pkg.changes['architecture'].keys())}).rowcount:
+            session.commit()
+            return
+
+        # Add current changelog text into changelogs_text table, return created ID
+        query = "INSERT INTO changelogs_text (changelog) VALUES (:changelog) RETURNING id"
+        ID = session.execute(query, {'changelog': self.pkg.changes['changes']}).fetchone()[0]
+
+        # Link ID to the upload available in changes table
+        query = """UPDATE changes SET changelog_id = :id WHERE source = :source
+                   AND version = :version AND architecture = :architecture"""
+        session.execute(query, {'id': ID, 'source': self.pkg.changes['source'], \
+                                'version': self.pkg.changes['version'], \
+                                'architecture': " ".join(self.pkg.changes['architecture'].keys())})
+
+        session.commit()