Merge ~cjwatson/launchpad:publish-by-null-datepublished into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: a96d92b6620778489bd90c445d9e5570ea4574dd
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:publish-by-null-datepublished
Merge into: launchpad:master
Diff against target: 374 lines (+112/-85)
8 files modified
database/sampledata/current-dev.sql (+1/-1)
database/sampledata/current.sql (+1/-1)
lib/lp/archivepublisher/publishing.py (+24/-17)
lib/lp/archivepublisher/scripts/publish_ftpmaster.py (+4/-7)
lib/lp/registry/model/distribution.py (+52/-52)
lib/lp/soyuz/interfaces/archive.py (+11/-1)
lib/lp/soyuz/model/archive.py (+15/-4)
lib/lp/soyuz/model/publishing.py (+4/-2)
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+384442@code.launchpad.net

Commit message

Publish based on NULL datepublished, not PENDING

Description of the change

PackagePublishingStatus conflates the intended state of the publication (published, superseded, deleted, obsolete) with the current on-disk state (pending, published, etc.). This makes it difficult to add variations needed to support Built-Using.

Instead of publishing rows whose status is PENDING, publish ones that have an active status and a NULL value for datepublished, indicating that they have never been published to disk but that they are intended to be.

The PENDING status remains for API compatibility and as a hint in the web UI, but it no longer controls publishing.

To post a comment you must log in.
3ab27f6... by Colin Watson

Publish based on NULL datepublished, not PENDING

PackagePublishingStatus conflates the intended state of the publication
(published, superseded, deleted, obsolete) with the current on-disk
state (pending, published, etc.). This makes it difficult to add
variations needed to support Built-Using.

Instead of publishing rows whose status is PENDING, publish ones that
have an active status and a NULL value for datepublished, indicating
that they have never been published to disk but that they are intended
to be.

The PENDING status remains for API compatibility and as a hint in the
web UI, but it no longer controls publishing.

Revision history for this message
William Grant (wgrant) :
review: Approve (code)
a96d92b... by Colin Watson

Only set PUBLISHED if current status is PENDING

In future we may have other active publishing statuses that should be
left as-is rather than set to PUBLISHED. Prepare for that now by being
slightly more careful in ArchivePublisherBase.setPublished.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/database/sampledata/current-dev.sql b/database/sampledata/current-dev.sql
2index 191dd40..64cb226 100644
3--- a/database/sampledata/current-dev.sql
4+++ b/database/sampledata/current-dev.sql
5@@ -4523,7 +4523,7 @@ INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseri
6 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (27, 33, 10, 2, 1, 3, '2007-07-09 13:44:00.10654', '2007-07-09 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 24, NULL, NULL, NULL);
7 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (28, 35, 1, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 26, NULL, NULL, NULL);
8 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (29, 20, 1, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 14, NULL, NULL, NULL);
9-INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (30, 36, 10, 2, 5, 7, '2007-08-09 21:28:12.106187', NULL, NULL, NULL, NULL, NULL, NULL, 0, 12, NULL, NULL, NULL, 27, NULL, NULL, NULL);
10+INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (30, 36, 10, 2, 5, 7, '2007-08-09 21:28:12.106187', '2007-08-09 21:28:13', NULL, NULL, NULL, NULL, NULL, 0, 12, NULL, NULL, NULL, 27, NULL, NULL, NULL);
11 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (31, 35, 10, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 10, NULL, NULL, NULL, 26, NULL, NULL, NULL);
12 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (32, 38, 14, 1, 1, 3, '2006-02-15 12:19:00.05741', NULL, NULL, NULL, NULL, NULL, NULL, 0, 16, NULL, NULL, NULL, 19, NULL, NULL, NULL);
13 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (33, 39, 1, 1, 1, 3, '2006-02-15 12:19:00.05741', NULL, NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 9, NULL, NULL, NULL);
14diff --git a/database/sampledata/current.sql b/database/sampledata/current.sql
15index be42368..5e9f4ea 100644
16--- a/database/sampledata/current.sql
17+++ b/database/sampledata/current.sql
18@@ -4447,7 +4447,7 @@ INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseri
19 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (27, 33, 10, 2, 1, 3, '2007-07-09 13:44:00.10654', '2007-07-09 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 24, NULL, NULL, NULL);
20 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (28, 35, 1, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 26, NULL, NULL, NULL);
21 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (29, 20, 1, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 14, NULL, NULL, NULL);
22-INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (30, 36, 10, 2, 5, 7, '2007-08-09 21:28:12.106187', NULL, NULL, NULL, NULL, NULL, NULL, 0, 12, NULL, NULL, NULL, 27, NULL, NULL, NULL);
23+INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (30, 36, 10, 2, 5, 7, '2007-08-09 21:28:12.106187', '2007-08-09 21:28:13', NULL, NULL, NULL, NULL, NULL, 0, 12, NULL, NULL, NULL, 27, NULL, NULL, NULL);
24 INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (31, 35, 10, 2, 1, 3, '2007-07-09 12:00:00', '2007-07-09 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 10, NULL, NULL, NULL, 26, NULL, NULL, NULL);
25
26
27diff --git a/lib/lp/archivepublisher/publishing.py b/lib/lp/archivepublisher/publishing.py
28index f6246b0..18f273a 100644
29--- a/lib/lp/archivepublisher/publishing.py
30+++ b/lib/lp/archivepublisher/publishing.py
31@@ -537,16 +537,21 @@ class Publisher(object):
32
33 def getPendingSourcePublications(self, is_careful):
34 """Return the specific group of source records to be published."""
35- # Careful publishing should include all PUBLISHED rows, normal run
36- # only includes PENDING ones.
37- statuses = [PackagePublishingStatus.PENDING]
38- if is_careful:
39- statuses.append(PackagePublishingStatus.PUBLISHED)
40+ # Careful publishing should include all rows in active statuses
41+ # regardless of whether they have previously been published; a
42+ # normal run only includes rows in active statuses that have never
43+ # been published.
44+ clauses = [
45+ SourcePackagePublishingHistory.archive == self.archive,
46+ SourcePackagePublishingHistory.status.is_in(
47+ active_publishing_status),
48+ ]
49+ if not is_careful:
50+ clauses.append(
51+ SourcePackagePublishingHistory.datepublished == None)
52
53 publications = IStore(SourcePackagePublishingHistory).find(
54- SourcePackagePublishingHistory,
55- SourcePackagePublishingHistory.archive == self.archive,
56- SourcePackagePublishingHistory.status.is_in(statuses))
57+ SourcePackagePublishingHistory, *clauses)
58 return publications.order_by(
59 SourcePackagePublishingHistory.distroseriesID,
60 SourcePackagePublishingHistory.pocket,
61@@ -588,19 +593,21 @@ class Publisher(object):
62
63 def getPendingBinaryPublications(self, is_careful):
64 """Return the specific group of binary records to be published."""
65- statuses = [PackagePublishingStatus.PENDING]
66- if is_careful:
67- statuses.append(PackagePublishingStatus.PUBLISHED)
68-
69- publications = IStore(BinaryPackagePublishingHistory).find(
70- BinaryPackagePublishingHistory,
71+ clauses = [
72 BinaryPackagePublishingHistory.archive == self.archive,
73 BinaryPackagePublishingHistory.distroarchseriesID ==
74 DistroArchSeries.id,
75- DistroArchSeries.distroseriesID == DistroSeries.id,
76- BinaryPackagePublishingHistory.status.is_in(statuses))
77+ BinaryPackagePublishingHistory.status.is_in(
78+ active_publishing_status),
79+ ]
80+ if not is_careful:
81+ clauses.append(
82+ BinaryPackagePublishingHistory.datepublished == None)
83+
84+ publications = IStore(BinaryPackagePublishingHistory).find(
85+ BinaryPackagePublishingHistory, *clauses)
86 return publications.order_by(
87- DistroSeries.id,
88+ DistroArchSeries.distroseriesID,
89 BinaryPackagePublishingHistory.pocket,
90 DistroArchSeries.architecturetag,
91 Desc(BinaryPackagePublishingHistory.id))
92diff --git a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
93index c307846..2610531 100644
94--- a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
95+++ b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
96@@ -43,10 +43,7 @@ from lp.services.scripts.base import (
97 LaunchpadScriptFailure,
98 )
99 from lp.services.utils import file_exists
100-from lp.soyuz.enums import (
101- ArchivePurpose,
102- PackagePublishingStatus,
103- )
104+from lp.soyuz.enums import ArchivePurpose
105 from lp.soyuz.model.distroarchseries import DistroArchSeries
106 from lp.soyuz.scripts.custom_uploads_copier import CustomUploadsCopier
107
108@@ -265,10 +262,10 @@ class PublishFTPMaster(LaunchpadCronScript):
109 self.logger.debug("Querying which suites are pending publication...")
110
111 archive = distribution.main_archive
112- pending = PackagePublishingStatus.PENDING
113- pending_sources = list(archive.getPublishedSources(status=pending))
114+ pending_sources = list(archive.getPublishedSources(
115+ only_unpublished=True))
116 pending_binaries = list(archive.getAllPublishedBinaries(
117- status=pending))
118+ only_unpublished=True))
119 load_related(
120 DistroArchSeries, pending_binaries, ['distroarchseriesID'])
121 return set(
122diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
123index 9c4c96e..33c1571 100644
124--- a/lib/lp/registry/model/distribution.py
125+++ b/lib/lp/registry/model/distribution.py
126@@ -176,6 +176,7 @@ from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
127 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
128 from lp.soyuz.interfaces.publishing import active_publishing_status
129 from lp.soyuz.model.archive import Archive
130+from lp.soyuz.model.archivefile import ArchiveFile
131 from lp.soyuz.model.binarypackagename import BinaryPackageName
132 from lp.soyuz.model.distributionsourcepackagerelease import (
133 DistributionSourcePackageRelease,
134@@ -1288,60 +1289,59 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
135
136 def getPendingPublicationPPAs(self):
137 """See `IDistribution`."""
138- src_query = """
139- Archive.purpose = %s AND
140- Archive.distribution = %s AND
141- SourcePackagePublishingHistory.archive = archive.id AND
142- SourcePackagePublishingHistory.scheduleddeletiondate IS NULL AND
143- SourcePackagePublishingHistory.dateremoved IS NULL AND
144- SourcePackagePublishingHistory.status IN (%s, %s)
145- """ % sqlvalues(ArchivePurpose.PPA, self,
146- PackagePublishingStatus.PENDING,
147- PackagePublishingStatus.DELETED)
148-
149- src_archives = Archive.select(
150- src_query, clauseTables=['SourcePackagePublishingHistory'],
151- orderBy=['archive.id'], distinct=True)
152-
153- bin_query = """
154- Archive.purpose = %s AND
155- Archive.distribution = %s AND
156- BinaryPackagePublishingHistory.archive = archive.id AND
157- BinaryPackagePublishingHistory.scheduleddeletiondate IS NULL AND
158- BinaryPackagePublishingHistory.dateremoved IS NULL AND
159- BinaryPackagePublishingHistory.status IN (%s, %s)
160- """ % sqlvalues(ArchivePurpose.PPA, self,
161- PackagePublishingStatus.PENDING,
162- PackagePublishingStatus.DELETED)
163-
164- bin_archives = Archive.select(
165- bin_query, clauseTables=['BinaryPackagePublishingHistory'],
166- orderBy=['archive.id'], distinct=True)
167-
168- reapable_af_query = """
169- Archive.purpose = %s AND
170- Archive.distribution = %s AND
171- ArchiveFile.archive = archive.id AND
172- ArchiveFile.scheduled_deletion_date < %s
173- """ % sqlvalues(ArchivePurpose.PPA, self, UTC_NOW)
174-
175- reapable_af_archives = Archive.select(
176- reapable_af_query, clauseTables=['ArchiveFile'],
177- orderBy=['archive.id'], distinct=True)
178-
179- dirty_suites_query = """
180- Archive.purpose = %s AND
181- Archive.distribution = %s AND
182- Archive.dirty_suites IS NOT NULL
183- """ % sqlvalues(ArchivePurpose.PPA, self)
184+ src_archives = IStore(Archive).find(
185+ Archive,
186+ Archive.purpose == ArchivePurpose.PPA,
187+ Archive.distribution == self,
188+ SourcePackagePublishingHistory.archive == Archive.id,
189+ SourcePackagePublishingHistory.scheduleddeletiondate == None,
190+ SourcePackagePublishingHistory.dateremoved == None,
191+ Or(
192+ And(
193+ SourcePackagePublishingHistory.status.is_in(
194+ active_publishing_status),
195+ SourcePackagePublishingHistory.datepublished == None),
196+ SourcePackagePublishingHistory.status ==
197+ PackagePublishingStatus.DELETED,
198+ )).order_by(Archive.id).config(distinct=True)
199+
200+ bin_archives = IStore(Archive).find(
201+ Archive,
202+ Archive.purpose == ArchivePurpose.PPA,
203+ Archive.distribution == self,
204+ BinaryPackagePublishingHistory.archive == Archive.id,
205+ BinaryPackagePublishingHistory.scheduleddeletiondate == None,
206+ BinaryPackagePublishingHistory.dateremoved == None,
207+ Or(
208+ And(
209+ BinaryPackagePublishingHistory.status.is_in(
210+ active_publishing_status),
211+ BinaryPackagePublishingHistory.datepublished == None),
212+ BinaryPackagePublishingHistory.status ==
213+ PackagePublishingStatus.DELETED,
214+ )).order_by(Archive.id).config(distinct=True)
215+
216+ reapable_af_archives = IStore(Archive).find(
217+ Archive,
218+ Archive.purpose == ArchivePurpose.PPA,
219+ Archive.distribution == self,
220+ ArchiveFile.archive == Archive.id,
221+ ArchiveFile.scheduled_deletion_date < UTC_NOW,
222+ ).order_by(Archive.id).config(distinct=True)
223
224- dirty_suites_archives = Archive.select(
225- dirty_suites_query, orderBy=['archive.id'])
226+ dirty_suites_archives = IStore(Archive).find(
227+ Archive,
228+ Archive.purpose == ArchivePurpose.PPA,
229+ Archive.distribution == self,
230+ Archive.dirty_suites != None,
231+ ).order_by(Archive.id)
232
233- deleting_archives = Archive.selectBy(
234- distribution=self,
235- purpose=ArchivePurpose.PPA,
236- status=ArchiveStatus.DELETING).orderBy(['archive.id'])
237+ deleting_archives = IStore(Archive).find(
238+ Archive,
239+ Archive.purpose == ArchivePurpose.PPA,
240+ Archive.distribution == self,
241+ Archive.status == ArchiveStatus.DELETING,
242+ ).order_by(Archive.id)
243
244 return src_archives.union(bin_archives).union(
245 reapable_af_archives).union(dirty_suites_archives).union(
246diff --git a/lib/lp/soyuz/interfaces/archive.py b/lib/lp/soyuz/interfaces/archive.py
247index 8d34ec4..0e82e27 100644
248--- a/lib/lp/soyuz/interfaces/archive.py
249+++ b/lib/lp/soyuz/interfaces/archive.py
250@@ -543,7 +543,8 @@ class IArchiveSubscriberView(Interface):
251 distroseries=None, pocket=None,
252 exact_match=False, created_since_date=None,
253 eager_load=False, component_name=None,
254- order_by_date=False):
255+ order_by_date=False, include_removed=True,
256+ only_unpublished=False):
257 """All `ISourcePackagePublishingHistory` target to this archive.
258
259 :param name: source name filter (exact match or SQL LIKE controlled
260@@ -566,6 +567,10 @@ class IArchiveSubscriberView(Interface):
261 If not specified, publications are ordered by source
262 package name (lexicographically), then by descending version
263 and then descending ID.
264+ :param include_removed: If True, include publications that have been
265+ removed from disk as well as those that have not.
266+ :param only_unpublished: If True, only include publications that
267+ have never been published to disk.
268
269 :return: SelectResults containing `ISourcePackagePublishingHistory`,
270 ordered by name. If there are multiple results for the same
271@@ -1239,6 +1244,7 @@ class IArchiveView(IHasBuildRecords):
272 distroarchseries=None, pocket=None,
273 exact_match=False, created_since_date=None,
274 ordered=True, order_by_date=False,
275+ include_removed=True, only_unpublished=False,
276 eager_load=False):
277 """All `IBinaryPackagePublishingHistory` target to this archive.
278
279@@ -1260,6 +1266,10 @@ class IArchiveView(IHasBuildRecords):
280 :param order_by_date: Order publications by descending creation date
281 and then by descending ID. This is suitable for applications
282 that need to catch up with publications since their last run.
283+ :param include_removed: If True, include publications that have been
284+ removed from disk as well as those that have not.
285+ :param only_unpublished: If True, only include publications that
286+ have never been published to disk.
287
288 :return: A collection containing `BinaryPackagePublishingHistory`.
289 """
290diff --git a/lib/lp/soyuz/model/archive.py b/lib/lp/soyuz/model/archive.py
291index c496824..acf8541 100644
292--- a/lib/lp/soyuz/model/archive.py
293+++ b/lib/lp/soyuz/model/archive.py
294@@ -617,7 +617,8 @@ class Archive(SQLBase):
295 distroseries=None, pocket=None,
296 exact_match=False, created_since_date=None,
297 eager_load=False, component_name=None,
298- order_by_date=False, include_removed=True):
299+ order_by_date=False, include_removed=True,
300+ only_unpublished=False):
301 """See `IArchive`."""
302 clauses = [SourcePackagePublishingHistory.archiveID == self.id]
303
304@@ -693,6 +694,10 @@ class Archive(SQLBase):
305 if not include_removed:
306 clauses.append(SourcePackagePublishingHistory.dateremoved == None)
307
308+ if only_unpublished:
309+ clauses.append(
310+ SourcePackagePublishingHistory.datepublished == None)
311+
312 store = Store.of(self)
313 resultset = store.find(
314 SourcePackagePublishingHistory, *clauses).order_by(*order_by)
315@@ -803,7 +808,7 @@ class Archive(SQLBase):
316 self, name=None, version=None, status=None, distroarchseries=None,
317 pocket=None, exact_match=False, created_since_date=None,
318 ordered=True, order_by_date=False, include_removed=True,
319- need_bpr=False):
320+ only_unpublished=False, need_bpr=False):
321 """Base clauses for binary publishing queries.
322
323 Returns a list of 'clauses' (to be joined in the callsite).
324@@ -880,13 +885,18 @@ class Archive(SQLBase):
325 if not include_removed:
326 clauses.append(BinaryPackagePublishingHistory.dateremoved == None)
327
328+ if only_unpublished:
329+ clauses.append(
330+ BinaryPackagePublishingHistory.datepublished == None)
331+
332 return clauses, order_by
333
334 def getAllPublishedBinaries(self, name=None, version=None, status=None,
335 distroarchseries=None, pocket=None,
336 exact_match=False, created_since_date=None,
337 ordered=True, order_by_date=False,
338- include_removed=True, eager_load=False):
339+ include_removed=True, only_unpublished=False,
340+ eager_load=False):
341 """See `IArchive`."""
342 # Circular imports.
343 from lp.registry.model.distroseries import DistroSeries
344@@ -896,7 +906,8 @@ class Archive(SQLBase):
345 name=name, version=version, status=status, pocket=pocket,
346 distroarchseries=distroarchseries, exact_match=exact_match,
347 created_since_date=created_since_date, ordered=ordered,
348- order_by_date=order_by_date, include_removed=include_removed)
349+ order_by_date=order_by_date, include_removed=include_removed,
350+ only_unpublished=only_unpublished)
351
352 result = Store.of(self).find(
353 BinaryPackagePublishingHistory, *clauses).order_by(*order_by)
354diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py
355index 1c5d384..5e6173a 100644
356--- a/lib/lp/soyuz/model/publishing.py
357+++ b/lib/lp/soyuz/model/publishing.py
358@@ -157,12 +157,14 @@ class ArchivePublisherBase:
359 """see IArchiveSafePublisher."""
360 # XXX cprov 2006-06-14:
361 # Implement sanity checks before set it as published
362- if self.status == PackagePublishingStatus.PENDING:
363+ if (self.status in active_publishing_status and
364+ self.datepublished is None):
365 # update the DB publishing record status if they
366 # are pending, don't do anything for the ones
367 # already published (usually when we use -C
368 # publish-distro.py option)
369- self.status = PackagePublishingStatus.PUBLISHED
370+ if self.status == PackagePublishingStatus.PENDING:
371+ self.status = PackagePublishingStatus.PUBLISHED
372 self.datepublished = UTC_NOW
373
374 def publish(self, diskpool, log):

Subscribers

People subscribed via source and target branches

to status/vote changes: