2 # vim:set et ts=4 sw=4:
4 """Utilities for handling changes files
6 @contact: Debian FTP Master <ftpmaster@debian.org>
7 @copyright: 2001, 2002, 2003, 2004, 2005, 2006 James Troup <james@nocrew.org>
8 @copyright: 2009 Joerg Jaspert <joerg@debian.org>
9 @copyright: 2009 Frank Lichtenheld <djpig@debian.org>
10 @license: GNU General Public License version 2 or later
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 ################################################################################
33 from daklib.dbconn import *
34 from daklib.queue import *
35 from daklib import utils
36 from daklib.config import Config
38 ################################################################################
42 ################################################################################
44 def indiv_sg_compare (a, b):
45 """Sort by source name, source, version, 'have source', and
46 finally by filename."""
47 # Sort by source version
48 q = apt_pkg.VersionCompare(a["version"], b["version"])
52 # Sort by 'have source'
53 a_has_source = a["architecture"].get("source")
54 b_has_source = b["architecture"].get("source")
55 if a_has_source and not b_has_source:
57 elif b_has_source and not a_has_source:
60 return cmp(a["filename"], b["filename"])
62 __all__.append('indiv_sg_compare')
64 ############################################################
66 def sg_compare (a, b):
69 """Sort by have note, source already in database and time of oldest upload."""
71 a_note_state = a["note_state"]
72 b_note_state = b["note_state"]
73 if a_note_state < b_note_state:
75 elif a_note_state > b_note_state:
77 # Sort by source already in database (descending)
78 source_in_database = cmp(a["source_in_database"], b["source_in_database"])
79 if source_in_database:
80 return -source_in_database
82 # Sort by time of oldest upload
83 return cmp(a["oldest"], b["oldest"])
85 __all__.append('sg_compare')
87 def sort_changes(changes_files, session, binaries = None):
88 """Sort into source groups, then sort each source group by version,
89 have source, filename. Finally, sort the source groups by have
90 note, time of oldest upload of each source upload."""
91 if len(changes_files) == 1:
96 # Read in all the .changes files
97 for filename in changes_files:
100 u.pkg.changes_file = filename
101 u.load_changes(filename)
103 cache[filename] = copy.copy(u.pkg.changes)
104 cache[filename]["filename"] = filename
106 sorted_list.append(filename)
108 # Divide the .changes into per-source groups
110 for filename in cache.keys():
111 source = cache[filename]["source"]
112 if not per_source.has_key(source):
113 per_source[source] = {}
114 per_source[source]["list"] = []
115 per_source[source]["list"].append(cache[filename])
116 # Determine oldest time and have note status for each source group
117 for source in per_source.keys():
118 q = session.query(DBSource).filter_by(source = source).all()
119 per_source[source]["source_in_database"] = binaries and -(len(q)>0) or len(q)>0
120 source_list = per_source[source]["list"]
121 first = source_list[0]
122 oldest = os.stat(first["filename"])[stat.ST_MTIME]
124 for d in per_source[source]["list"]:
125 mtime = os.stat(d["filename"])[stat.ST_MTIME]
128 have_note += has_new_comment(d["source"], d["version"], session)
129 per_source[source]["oldest"] = oldest
131 per_source[source]["note_state"] = 0; # none
132 elif have_note < len(source_list):
133 per_source[source]["note_state"] = 1; # some
135 per_source[source]["note_state"] = 2; # all
136 per_source[source]["list"].sort(indiv_sg_compare)
137 per_source_items = per_source.items()
138 per_source_items.sort(sg_compare)
139 for i in per_source_items:
140 for j in i[1]["list"]:
141 sorted_list.append(j["filename"])
144 __all__.append('sort_changes')
146 ################################################################################
148 def changes_to_queue(upload, srcqueue, destqueue, session):
149 """Move a changes file to a different queue and mark as approved for the
153 chg = session.query(DBChange).filter_by(changesname=os.path.basename(upload.pkg.changes_file)).one()
154 except NoResultFound:
157 chg.approved_for_id = srcqueue.policy_queue_id
160 # update the changes_pending_files row
162 # Only worry about unprocessed files
164 utils.move(os.path.join(srcqueue.path, f.filename), destqueue.path, perms=int(destqueue.perms, 8))
166 utils.move(os.path.join(srcqueue.path, upload.pkg.changes_file), destqueue.path, perms=int(destqueue.perms, 8))
167 chg.in_queue = destqueue
172 __all__.append('changes_to_queue')
174 def new_accept(upload, dry_run, session):
180 (summary, short_summary) = upload.build_summaries()
181 destqueue = get_policy_queue('newstage', session)
183 srcqueue = get_policy_queue_from_path(upload.pkg.directory, session)
186 # Assume NEW and hope for the best
187 srcqueue = get_policy_queue('new', session)
189 changes_to_queue(upload, srcqueue, destqueue, session)
191 __all__.append('new_accept')