8687.15.34
by Karl Fogel
Add license header blocks to .py, .zcml, and .pt files that don't have it |
1 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
3 |
|
4 |
"""Implementation for the IRevisionCache and IRevisionCollection."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
__all__ = [ |
|
8 |
'GenericRevisionCollection', |
|
9 |
]
|
|
10 |
||
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
11 |
from datetime import ( |
12 |
datetime, |
|
13 |
timedelta, |
|
14 |
)
|
|
8786.1.10
by Tim Penhey
authoredBy works. |
15 |
|
16 |
import pytz |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
17 |
from storm.expr import ( |
18 |
Desc, |
|
19 |
Func, |
|
20 |
SQL, |
|
21 |
)
|
|
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
22 |
from zope.component import getUtility |
23 |
from zope.interface import implements |
|
24 |
||
25 |
from canonical.launchpad.webapp.interfaces import ( |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
26 |
DEFAULT_FLAVOR, |
27 |
IStoreSelector, |
|
28 |
MAIN_STORE, |
|
29 |
)
|
|
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
30 |
from lp.code.interfaces.revisioncache import IRevisionCollection |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
31 |
from lp.code.model.revision import ( |
32 |
Revision, |
|
33 |
RevisionAuthor, |
|
34 |
RevisionCache, |
|
35 |
)
|
|
8786.1.8
by Tim Penhey
inDistribution works.# |
36 |
from lp.registry.model.distroseries import DistroSeries |
8786.1.6
by Tim Penhey
inProject working |
37 |
from lp.registry.model.product import Product |
8786.1.10
by Tim Penhey
authoredBy works. |
38 |
from lp.registry.model.teammembership import TeamParticipation |
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
39 |
|
40 |
||
41 |
class GenericRevisionCollection: |
|
42 |
"""See `IRevisionCollection`."""
|
|
43 |
||
44 |
implements(IRevisionCollection) |
|
45 |
||
46 |
def __init__(self, store=None, filter_expressions=None): |
|
47 |
self._store = store |
|
48 |
if filter_expressions is None: |
|
8786.1.16
by Tim Penhey
Add in authorCount. |
49 |
epoch = datetime.now(pytz.UTC) - timedelta(days=30) |
50 |
filter_expressions = [ |
|
51 |
RevisionCache.revision_date >= epoch] |
|
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
52 |
self._filter_expressions = filter_expressions |
53 |
||
54 |
@property
|
|
55 |
def store(self): |
|
56 |
# Although you might think we could set the default value for store in
|
|
57 |
# the constructor, we can't. The IStoreSelector utility is not
|
|
58 |
# available at the time that the branchcollection.zcml is parsed,
|
|
59 |
# which means we get an error if this code is in the constructor.
|
|
60 |
if self._store is None: |
|
61 |
return getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
|
62 |
else: |
|
63 |
return self._store |
|
64 |
||
65 |
def _filterBy(self, expressions): |
|
66 |
return self.__class__( |
|
67 |
self.store, |
|
68 |
self._filter_expressions + expressions) |
|
69 |
||
70 |
def count(self): |
|
71 |
"""See `IRevisionCollection`."""
|
|
8786.1.16
by Tim Penhey
Add in authorCount. |
72 |
result_set = self.store.find( |
73 |
RevisionCache.revision_id, self._filter_expressions) |
|
74 |
result_set.config(distinct=True) |
|
75 |
return result_set.count() |
|
76 |
||
77 |
def authorCount(self): |
|
78 |
"""See `IRevisionCollection`."""
|
|
8786.1.22
by Tim Penhey
New test for non-linked revision authors. |
79 |
# Revision authors that are linked to Launchpad people are only
|
8786.1.23
by Tim Penhey
Clean up the comment. |
80 |
# counted once even if the revision text that they use in the commit
|
8786.1.22
by Tim Penhey
New test for non-linked revision authors. |
81 |
# is different.
|
8786.1.16
by Tim Penhey
Add in authorCount. |
82 |
author = Func( |
83 |
'coalesce', |
|
84 |
RevisionAuthor.personID, |
|
85 |
SQL(0) - RevisionAuthor.id) |
|
86 |
expressions = [ |
|
87 |
RevisionCache.revision_author == RevisionAuthor.id] |
|
88 |
expressions.extend(self._filter_expressions) |
|
89 |
result_set = self.store.find(author, expressions) |
|
90 |
result_set.config(distinct=True) |
|
91 |
return result_set.count() |
|
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
92 |
|
93 |
def getRevisions(self): |
|
94 |
"""See `IRevisionCollection`."""
|
|
8786.1.10
by Tim Penhey
authoredBy works. |
95 |
expressions = [ |
8786.1.16
by Tim Penhey
Add in authorCount. |
96 |
RevisionCache.revision == Revision.id] |
8786.1.2
by Tim Penhey
Write enough to get the tests passing. |
97 |
expressions.extend(self._filter_expressions) |
8786.1.3
by Tim Penhey
More tests pass. |
98 |
result_set = self.store.find(Revision, expressions) |
99 |
result_set.config(distinct=True) |
|
8786.1.11
by Tim Penhey
date check works. |
100 |
result_set.order_by(Desc(Revision.revision_date)) |
8786.1.3
by Tim Penhey
More tests pass. |
101 |
return result_set |
8786.1.4
by Tim Penhey
Public restriction tested. |
102 |
|
103 |
def public(self): |
|
104 |
"""See `IRevisionCollection`."""
|
|
105 |
return self._filterBy( |
|
106 |
[RevisionCache.private == False]) |
|
8786.1.5
by Tim Penhey
inProduct working. |
107 |
|
108 |
def inProduct(self, product): |
|
109 |
"""See `IRevisionCollection`."""
|
|
110 |
return self._filterBy( |
|
111 |
[RevisionCache.product == product]) |
|
8786.1.6
by Tim Penhey
inProject working |
112 |
|
113 |
def inProject(self, project): |
|
114 |
"""See `IRevisionCollection`."""
|
|
115 |
return self._filterBy( |
|
116 |
[RevisionCache.product == Product.id, |
|
117 |
Product.project == project]) |
|
8786.1.7
by Tim Penhey
inSourcePackage tested |
118 |
|
119 |
def inSourcePackage(self, package): |
|
120 |
"""See `IRevisionCollection`."""
|
|
121 |
return self._filterBy( |
|
122 |
[RevisionCache.distroseries == package.distroseries, |
|
123 |
RevisionCache.sourcepackagename == package.sourcepackagename]) |
|
8786.1.8
by Tim Penhey
inDistribution works.# |
124 |
|
125 |
def inDistribution(self, distribution): |
|
126 |
"""See `IRevisionCollection`."""
|
|
127 |
return self._filterBy( |
|
128 |
[DistroSeries.distribution == distribution, |
|
129 |
RevisionCache.distroseries == DistroSeries.id]) |
|
8786.1.9
by Tim Penhey
distroseries and distribution source packages are now filtered too. |
130 |
|
131 |
def inDistroSeries(self, distro_series): |
|
132 |
"""See `IRevisionCollection`."""
|
|
133 |
return self._filterBy( |
|
134 |
[RevisionCache.distroseries == distro_series]) |
|
135 |
||
136 |
def inDistributionSourcePackage(self, distro_source_package): |
|
8786.1.10
by Tim Penhey
authoredBy works. |
137 |
"""See `IRevisionCollection`."""
|
8786.1.9
by Tim Penhey
distroseries and distribution source packages are now filtered too. |
138 |
distribution = distro_source_package.distribution |
139 |
sourcepackagename = distro_source_package.sourcepackagename |
|
140 |
return self._filterBy( |
|
141 |
[DistroSeries.distribution == distribution, |
|
142 |
RevisionCache.distroseries == DistroSeries.id, |
|
143 |
RevisionCache.sourcepackagename == sourcepackagename]) |
|
8786.1.10
by Tim Penhey
authoredBy works. |
144 |
|
145 |
def authoredBy(self, person): |
|
146 |
"""See `IRevisionCollection`."""
|
|
147 |
if person.is_team: |
|
148 |
query = [ |
|
149 |
TeamParticipation.team == person, |
|
150 |
RevisionAuthor.personID == TeamParticipation.personID] |
|
151 |
else: |
|
152 |
query = [RevisionAuthor.person == person] |
|
153 |
||
154 |
query.append(RevisionCache.revision_author == RevisionAuthor.id) |
|
155 |
return self._filterBy(query) |