8687.15.17
by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/. |
1 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
3 |
|
4 |
"""Branch feed (syndication) views."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
||
8 |
__all__ = [ |
|
9 |
'BranchFeed', |
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
10 |
'PersonBranchFeed', |
6736.3.1
by Tim Penhey
Initial work. |
11 |
'PersonRevisionFeed', |
5204.6.5
by Brad Crittenden
unworking checkpoint |
12 |
'ProductBranchFeed', |
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
13 |
'ProductRevisionFeed', |
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
14 |
'ProjectBranchFeed', |
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
15 |
'ProjectRevisionFeed', |
5204.6.2
by Brad Crittenden
non-working checkpoint |
16 |
]
|
17 |
||
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
18 |
from storm.locals import ( |
19 |
Asc, |
|
20 |
Desc, |
|
21 |
)
|
|
22 |
from z3c.ptcompat import ViewPageTemplateFile |
|
6194.3.1
by Paul Hummer
Fixed bug-192010 - The branches now sort correctly in a feed |
23 |
from zope.component import getUtility |
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
24 |
from zope.interface import implements |
5204.6.2
by Brad Crittenden
non-working checkpoint |
25 |
from zope.security.interfaces import Unauthorized |
26 |
||
8138.1.2
by Jonathan Lange
Run migrater over lp.code. Many tests broken and imports failing. |
27 |
from lp.code.browser.branch import BranchView |
28 |
from lp.code.interfaces.branch import ( |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
29 |
DEFAULT_BRANCH_STATUS_IN_LISTING, |
30 |
IBranch, |
|
31 |
)
|
|
8138.1.2
by Jonathan Lange
Run migrater over lp.code. Many tests broken and imports failing. |
32 |
from lp.code.interfaces.branchcollection import IAllBranches |
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
33 |
from lp.code.interfaces.revisioncache import IRevisionCache |
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
34 |
from lp.registry.interfaces.person import IPerson |
35 |
from lp.registry.interfaces.product import IProduct |
|
10326.1.2
by Henning Eggers
Renamed project interfaces module to projectgroup. |
36 |
from lp.registry.interfaces.projectgroup import IProjectGroup |
14606.4.2
by William Grant
merge canonical.lazr.feed into lp.services.feeds. |
37 |
from lp.services.config import config |
38 |
from lp.services.feeds.feed import ( |
|
39 |
FeedBase, |
|
40 |
FeedEntry, |
|
41 |
FeedPerson, |
|
42 |
FeedTypedData, |
|
43 |
MINUTES, |
|
44 |
)
|
|
14606.4.3
by William Grant
Move the interfaces across too. |
45 |
from lp.services.feeds.interfaces.feed import IFeedPerson |
11382.6.34
by Gavin Panella
Reformat imports in all files touched so far. |
46 |
from lp.services.propertycache import cachedproperty |
14606.4.2
by William Grant
merge canonical.lazr.feed into lp.services.feeds. |
47 |
from lp.services.webapp import ( |
48 |
canonical_url, |
|
49 |
LaunchpadView, |
|
50 |
urlparse, |
|
51 |
)
|
|
52 |
from lp.services.webapp.interfaces import ILaunchpadRoot |
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
53 |
|
54 |
||
8931.2.3
by Tim Penhey
More tests. |
55 |
def revision_feed_id(revision): |
56 |
"""Return a consistent id for a revision to use as an id."""
|
|
57 |
return "tag:launchpad.net,%s:/revision/%s" % ( |
|
58 |
revision.revision_date.date().isoformat(), revision.revision_id) |
|
59 |
||
60 |
||
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
61 |
class BranchFeedEntry(FeedEntry): |
62 |
"""See `IFeedEntry`."""
|
|
63 |
def construct_id(self): |
|
64 |
url_path = urlparse(self.link_alternate)[2] |
|
65 |
return 'tag:launchpad.net,%s:/code%s' % ( |
|
66 |
self.date_created.date().isoformat(), |
|
67 |
url_path) |
|
68 |
||
69 |
||
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
70 |
class BranchFeedContentView(BranchView): |
71 |
"""View for branch feed contents."""
|
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
72 |
|
5204.6.27
by Brad Crittenden
Added tests for single branch feed. |
73 |
def __init__(self, context, request, feed, |
74 |
template='templates/branch.pt'): |
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
75 |
super(BranchFeedContentView, self).__init__(context, request) |
76 |
self.feed = feed |
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
77 |
self.template_ = template |
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
78 |
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
79 |
def render(self): |
80 |
"""Render the view."""
|
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
81 |
return ViewPageTemplateFile(self.template_)(self) |
5204.6.2
by Brad Crittenden
non-working checkpoint |
82 |
|
83 |
||
84 |
class BranchFeedBase(FeedBase): |
|
85 |
"""Abstract class for branch feeds."""
|
|
86 |
||
87 |
# max_age is in seconds
|
|
88 |
max_age = config.launchpad.max_branch_feed_cache_minutes * MINUTES |
|
89 |
||
90 |
rootsite = "code" |
|
91 |
||
92 |
@property
|
|
93 |
def logo(self): |
|
94 |
"""See `IFeed`."""
|
|
95 |
return "%s/@@/branch" % self.site_url |
|
96 |
||
97 |
def _getRawItems(self): |
|
98 |
"""Get the raw set of items for the feed."""
|
|
99 |
raise NotImplementedError |
|
100 |
||
101 |
def getPublicRawItems(self): |
|
102 |
"""Private branchess are not to be shown in feeds.
|
|
103 |
||
104 |
The list of branches is screened to ensure no private branches are
|
|
105 |
returned.
|
|
106 |
"""
|
|
107 |
return [branch |
|
108 |
for branch in self._getRawItems() |
|
109 |
if not branch.private] |
|
110 |
||
5958.2.7
by Brad Crittenden
Changed getItemsWorker to _getItemsWorker. |
111 |
def _getItemsWorker(self): |
5958.2.4
by Brad Crittenden
Added caching to the getItems method for Feeds. |
112 |
"""Create the list of items.
|
113 |
||
114 |
Called by getItems which may cache the results.
|
|
115 |
"""
|
|
5204.6.2
by Brad Crittenden
non-working checkpoint |
116 |
items = self.getPublicRawItems() |
117 |
# Convert the items into their feed entry representation.
|
|
118 |
items = [self.itemToFeedEntry(item) for item in items] |
|
119 |
return items |
|
120 |
||
121 |
def itemToFeedEntry(self, branch): |
|
122 |
"""See `IFeed`."""
|
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
123 |
title = FeedTypedData(branch.displayname) |
5204.6.2
by Brad Crittenden
non-working checkpoint |
124 |
url = canonical_url(branch, rootsite=self.rootsite) |
5204.6.5
by Brad Crittenden
unworking checkpoint |
125 |
content_view = BranchFeedContentView(branch, self.request, self) |
5204.6.35
by Brad Crittenden
Correct relative hrefs in feeds. Removed duplicate branch entries. |
126 |
content = content_view.render() |
127 |
content_data = FeedTypedData(content=content, |
|
128 |
content_type="html", |
|
129 |
root_url=self.root_url) |
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
130 |
entry = BranchFeedEntry(title=title, |
131 |
link_alternate=url, |
|
132 |
date_created=branch.date_created, |
|
133 |
date_updated=branch.date_last_modified, |
|
134 |
date_published=branch.date_created, |
|
6916.1.1
by Curtis Hovey
Fixed comment formats to fidn missing persons, dates, and some bugs. |
135 |
# XXX bac 2008-01-10: if author and owner are
|
136 |
# different perhaps we should use them both?
|
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
137 |
authors=[FeedPerson(branch.owner, |
138 |
self.rootsite)], |
|
5204.6.35
by Brad Crittenden
Correct relative hrefs in feeds. Removed duplicate branch entries. |
139 |
content=content_data) |
5204.6.2
by Brad Crittenden
non-working checkpoint |
140 |
return entry |
141 |
||
142 |
||
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
143 |
class BranchListingFeed(BranchFeedBase): |
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
144 |
"""Feed for all branches on a product or project."""
|
5204.6.5
by Brad Crittenden
unworking checkpoint |
145 |
|
146 |
feedname = "branches" |
|
147 |
||
148 |
@property
|
|
149 |
def title(self): |
|
150 |
"""See `IFeed`."""
|
|
151 |
return "Branches for %s" % self.context.displayname |
|
152 |
||
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
153 |
def _getCollection(self): |
154 |
"""Return the collection that `BranchListingFeed_getRawItems` uses."""
|
|
155 |
raise NotImplementedError(self._getCollection) |
|
156 |
||
6266.2.1
by Tim Penhey
Refactor the many getBranchesForXXX into a single getBranchesForContext. |
157 |
def _getRawItems(self): |
158 |
"""See `BranchFeedBase._getRawItems`.
|
|
159 |
||
160 |
Return the branches for this context sorted by date_created in
|
|
161 |
descending order.
|
|
6736.3.19
by Tim Penhey
Updates following review. |
162 |
|
163 |
Only `self.quantity` revisions are returned.
|
|
6266.2.1
by Tim Penhey
Refactor the many getBranchesForXXX into a single getBranchesForContext. |
164 |
"""
|
8138.1.2
by Jonathan Lange
Run migrater over lp.code. Many tests broken and imports failing. |
165 |
from lp.code.model.branch import Branch |
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
166 |
collection = self._getCollection().visibleByUser( |
167 |
None).withLifecycleStatus(*DEFAULT_BRANCH_STATUS_IN_LISTING) |
|
12504.1.3
by Robert Collins
Reject reversion of this branch on trunk. |
168 |
branches = collection.getBranches(eager_load=False) |
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
169 |
branches.order_by( |
170 |
Desc(Branch.date_last_modified), |
|
7675.171.8
by Tim Penhey
Make the feed use the target_suffix instead of product.name. |
171 |
Asc(Branch.target_suffix), |
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
172 |
Desc(Branch.lifecycle_status), |
173 |
Asc(Branch.name)) |
|
174 |
branches.config(limit=self.quantity) |
|
175 |
return list(branches) |
|
6266.2.1
by Tim Penhey
Refactor the many getBranchesForXXX into a single getBranchesForContext. |
176 |
|
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
177 |
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
178 |
class ProductBranchFeed(BranchListingFeed): |
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
179 |
"""Feed for all branches on a product."""
|
180 |
||
181 |
usedfor = IProduct |
|
6194.3.1
by Paul Hummer
Fixed bug-192010 - The branches now sort correctly in a feed |
182 |
|
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
183 |
def _getCollection(self): |
184 |
return getUtility(IAllBranches).inProduct(self.context) |
|
185 |
||
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
186 |
|
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
187 |
class ProjectBranchFeed(BranchListingFeed): |
5204.6.6
by Brad Crittenden
Refactored project and product branch feeds. |
188 |
"""Feed for all branches on a product."""
|
189 |
||
10326.1.1
by Henning Eggers
Mechanically renamed IProject* to IProjectGroup*. |
190 |
usedfor = IProjectGroup |
6194.3.1
by Paul Hummer
Fixed bug-192010 - The branches now sort correctly in a feed |
191 |
|
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
192 |
def _getCollection(self): |
193 |
return getUtility(IAllBranches).inProject(self.context) |
|
194 |
||
5204.6.21
by Brad Crittenden
Added branch feed for a person. |
195 |
|
196 |
class PersonBranchFeed(BranchListingFeed): |
|
197 |
"""Feed for a person's branches."""
|
|
198 |
||
199 |
usedfor = IPerson |
|
6194.3.1
by Paul Hummer
Fixed bug-192010 - The branches now sort correctly in a feed |
200 |
|
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
201 |
def _getCollection(self): |
7860.1.2
by Jonathan Lange
Make the person branch feed only show branches owned by the person. |
202 |
return getUtility(IAllBranches).ownedBy(self.context) |
7860.1.1
by Jonathan Lange
Make the branch feed view use collections. |
203 |
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
204 |
|
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
205 |
class RevisionFeedContentView(LaunchpadView): |
6736.3.12
by Tim Penhey
Updates following review. |
206 |
"""View for a revision feed contents."""
|
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
207 |
|
208 |
def __init__(self, context, request, feed): |
|
209 |
super(RevisionFeedContentView, self).__init__(context, request) |
|
210 |
self.feed = feed |
|
211 |
||
6736.3.6
by Tim Penhey
Update the look of the feed. |
212 |
@cachedproperty
|
213 |
def branch(self): |
|
214 |
return self.context.getBranch() |
|
215 |
||
216 |
@cachedproperty
|
|
217 |
def revno(self): |
|
218 |
return self.branch.getBranchRevision(revision=self.context).sequence |
|
219 |
||
220 |
@property
|
|
221 |
def product(self): |
|
222 |
return self.branch.product |
|
223 |
||
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
224 |
def render(self): |
225 |
"""Render the view."""
|
|
226 |
return ViewPageTemplateFile('templates/revision.pt')(self) |
|
227 |
||
6736.3.6
by Tim Penhey
Update the look of the feed. |
228 |
@property
|
229 |
def title(self): |
|
230 |
if self.revno is None: |
|
231 |
revno = "" |
|
232 |
else: |
|
233 |
revno = "r%s " % self.revno |
|
234 |
log_lines = self.context.log_body.split('\n') |
|
235 |
first_line = log_lines[0] |
|
236 |
if len(first_line) < 60 and len(log_lines) == 1: |
|
237 |
logline = first_line |
|
238 |
else: |
|
239 |
logline = first_line[:60] + '...' |
|
240 |
return "[%(branch)s] %(revno)s %(logline)s" % { |
|
6736.3.9
by Tim Penhey
Fix the tests. |
241 |
'branch': self.branch.name, |
6736.3.6
by Tim Penhey
Update the look of the feed. |
242 |
'revno': revno, |
243 |
'logline': logline} |
|
244 |
||
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
245 |
|
6736.3.1
by Tim Penhey
Initial work. |
246 |
class RevisionListingFeed(FeedBase): |
247 |
"""Abstract class for revision feeds."""
|
|
248 |
||
249 |
# max_age is in seconds
|
|
250 |
max_age = config.launchpad.max_revision_feed_cache_minutes * MINUTES |
|
251 |
||
252 |
rootsite = "code" |
|
253 |
feedname = "revisions" |
|
254 |
||
255 |
@property
|
|
256 |
def logo(self): |
|
257 |
"""See `IFeed`."""
|
|
258 |
return "%s/@@/branch" % self.site_url |
|
259 |
||
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
260 |
def _getRevisionCache(self): |
261 |
"""Return the revision cache limited to the revision context."""
|
|
8786.2.1
by Tim Penhey
Updates following review. |
262 |
raise NotImplementedError(self._getRevisionCache) |
6736.3.1
by Tim Penhey
Initial work. |
263 |
|
264 |
def _getItemsWorker(self): |
|
265 |
"""Create the list of items.
|
|
266 |
||
267 |
Called by getItems which may cache the results.
|
|
268 |
"""
|
|
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
269 |
cache = self._getRevisionCache() |
8931.2.1
by Tim Penhey
Skip revisions that are no longer associated with branches. |
270 |
revisions = cache.public().getRevisions() |
6736.3.1
by Tim Penhey
Initial work. |
271 |
# Convert the items into their feed entry representation.
|
8931.2.1
by Tim Penhey
Skip revisions that are no longer associated with branches. |
272 |
items = [] |
273 |
for revision in revisions: |
|
8931.2.2
by Tim Penhey
Updates following review. |
274 |
content_view = self._createView(revision) |
275 |
if content_view is not None: |
|
276 |
entry = self.createFeedEntry(content_view) |
|
8931.2.1
by Tim Penhey
Skip revisions that are no longer associated with branches. |
277 |
items.append(entry) |
278 |
# If we've hit our limit, stop iterating the revisions.
|
|
279 |
if len(items) >= self.quantity: |
|
280 |
break
|
|
6736.3.1
by Tim Penhey
Initial work. |
281 |
return items |
282 |
||
8931.2.1
by Tim Penhey
Skip revisions that are no longer associated with branches. |
283 |
def _createView(self, revision): |
284 |
"""Make a view for this revision.
|
|
285 |
||
286 |
:return: A view class, or None.
|
|
287 |
"""
|
|
288 |
content_view = RevisionFeedContentView(revision, self.request, self) |
|
289 |
# If there is no longer an associated branch for this, return None as
|
|
290 |
# we don't want to show this revision.
|
|
291 |
if content_view.branch is None: |
|
292 |
return None |
|
293 |
return content_view |
|
294 |
||
295 |
def createFeedEntry(self, content_view): |
|
296 |
"""Create the FeedEntry for the specified view."""
|
|
297 |
revision = content_view.context |
|
8931.2.3
by Tim Penhey
More tests. |
298 |
id = revision_feed_id(revision) |
6736.3.1
by Tim Penhey
Initial work. |
299 |
content = content_view.render() |
300 |
content_data = FeedTypedData(content=content, |
|
301 |
content_type="html", |
|
302 |
root_url=self.root_url) |
|
6736.3.6
by Tim Penhey
Update the look of the feed. |
303 |
title = FeedTypedData(content_view.title) |
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
304 |
if revision.revision_author.person is None: |
305 |
authors = [ |
|
306 |
RevisionPerson(revision.revision_author, self.rootsite)] |
|
307 |
else: |
|
308 |
authors = [ |
|
309 |
FeedPerson(revision.revision_author.person, self.rootsite)] |
|
310 |
||
311 |
entry = FeedEntry( |
|
312 |
title=title, |
|
313 |
link_alternate=None, |
|
314 |
date_created=revision.revision_date, |
|
315 |
date_updated=revision.revision_date, |
|
316 |
date_published=revision.date_created, |
|
317 |
authors=authors, |
|
6736.3.7
by Tim Penhey
Add the feed doctest. |
318 |
id_=id, |
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
319 |
content=content_data) |
6736.3.1
by Tim Penhey
Initial work. |
320 |
return entry |
321 |
||
322 |
||
323 |
class PersonRevisionFeed(RevisionListingFeed): |
|
324 |
"""Feed for a person's revisions."""
|
|
325 |
||
326 |
usedfor = IPerson |
|
327 |
||
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
328 |
@property
|
329 |
def title(self): |
|
330 |
"""See `IFeed`."""
|
|
331 |
if self.context.is_team: |
|
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
332 |
return 'Latest Revisions by members of %s' % ( |
333 |
self.context.displayname) |
|
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
334 |
else: |
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
335 |
return 'Latest Revisions by %s' % self.context.displayname |
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
336 |
|
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
337 |
def _getRevisionCache(self): |
338 |
"""See `RevisionListingFeed`."""
|
|
339 |
return getUtility(IRevisionCache).authoredBy(self.context) |
|
6736.3.1
by Tim Penhey
Initial work. |
340 |
|
341 |
||
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
342 |
class ProjectRevisionFeedBase(RevisionListingFeed): |
343 |
"""Defines a common access method to get the revisions."""
|
|
344 |
||
345 |
@property
|
|
346 |
def title(self): |
|
347 |
"""See `IFeed`."""
|
|
348 |
return 'Latest Revisions for %s' % self.context.displayname |
|
349 |
||
350 |
||
351 |
class ProductRevisionFeed(ProjectRevisionFeedBase): |
|
352 |
"""Feed for a project's revisions."""
|
|
353 |
||
354 |
usedfor = IProduct |
|
355 |
||
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
356 |
def _getRevisionCache(self): |
357 |
"""See `RevisionListingFeed`."""
|
|
358 |
return getUtility(IRevisionCache).inProduct(self.context) |
|
6736.3.23
by Tim Penhey
Fix the feed's getRawItems method of revision acquisition. |
359 |
|
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
360 |
|
361 |
class ProjectRevisionFeed(ProjectRevisionFeedBase): |
|
362 |
"""Feed for a project's revisions."""
|
|
363 |
||
10326.1.1
by Henning Eggers
Mechanically renamed IProject* to IProjectGroup*. |
364 |
usedfor = IProjectGroup |
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
365 |
|
8786.1.13
by Tim Penhey
Make the feeds use the revision cache. |
366 |
def _getRevisionCache(self): |
367 |
"""See `RevisionListingFeed`."""
|
|
368 |
return getUtility(IRevisionCache).inProject(self.context) |
|
6736.3.23
by Tim Penhey
Fix the feed's getRawItems method of revision acquisition. |
369 |
|
6736.3.16
by Tim Penhey
Add the revision feed for products and projects. |
370 |
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
371 |
class RevisionPerson: |
372 |
"""See `IFeedPerson`.
|
|
373 |
||
374 |
Uses the `name_without_email` property for the display name.
|
|
375 |
"""
|
|
376 |
implements(IFeedPerson) |
|
377 |
||
378 |
def __init__(self, person, rootsite): |
|
379 |
||
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
380 |
no_email = person.name_without_email |
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
381 |
if no_email: |
382 |
self.name = no_email |
|
383 |
else: |
|
384 |
self.name = person.name |
|
385 |
# We don't want to disclose email addresses in public feeds.
|
|
386 |
self.email = None |
|
387 |
self.uri = None |
|
388 |
||
6736.3.4
by Tim Penhey
Added tests for addition Revision and RevisionSet methods. |
389 |
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
390 |
class BranchFeed(BranchFeedBase): |
391 |
"""Feed for single branch.
|
|
392 |
||
393 |
Unlike the other branch feeds, where the feed entries were the various
|
|
394 |
branches for that object, the feed for a single branch has as entries the
|
|
395 |
latest revisions for that branch.
|
|
396 |
"""
|
|
397 |
||
398 |
usedfor = IBranch |
|
399 |
feedname = "branch" |
|
400 |
||
401 |
def initialize(self): |
|
402 |
"""See `IFeed`."""
|
|
403 |
# For a `BranchFeed` we must ensure that the branch is not private.
|
|
404 |
super(BranchFeed, self).initialize() |
|
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
405 |
try: |
406 |
feed_allowed = not self.context.private |
|
407 |
if not feed_allowed: |
|
408 |
# We are logged in and can see the branch so redirect to the
|
|
409 |
# branch index page.
|
|
13082.2.5
by Ian Booth
Code review fixes |
410 |
message_prefix = "This branch is private." |
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
411 |
redirect_url = canonical_url(self.context) |
412 |
except Unauthorized: |
|
413 |
# Branch cannot be seen so redirect to the code index page.
|
|
414 |
feed_allowed = False |
|
13082.2.5
by Ian Booth
Code review fixes |
415 |
message_prefix = "The requested branch is private." |
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
416 |
root = getUtility(ILaunchpadRoot) |
417 |
redirect_url = canonical_url(root, rootsite='code') |
|
418 |
||
419 |
if not feed_allowed: |
|
420 |
self.request.response.addErrorNotification( |
|
13082.2.5
by Ian Booth
Code review fixes |
421 |
message_prefix + |
422 |
" Feeds do not serve private branches.") |
|
13082.2.2
by Ian Booth
Redirect to a senisble page with an error message if attempt is made to get an rss feed for a private bug/branch |
423 |
self.request.response.redirect(redirect_url) |
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
424 |
|
425 |
@property
|
|
426 |
def title(self): |
|
427 |
"""See `IFeed`."""
|
|
428 |
return "Latest Revisions for Branch %s" % self.context.displayname |
|
429 |
||
430 |
def _getRawItems(self): |
|
431 |
"""Get the raw set of items for the feed.
|
|
432 |
||
433 |
For a `BranchFeed` the items are the revisions for the branch.
|
|
434 |
"""
|
|
435 |
branch = self.context |
|
436 |
return branch.latest_revisions(quantity=self.quantity) |
|
437 |
||
5958.2.7
by Brad Crittenden
Changed getItemsWorker to _getItemsWorker. |
438 |
def _getItemsWorker(self): |
5958.2.4
by Brad Crittenden
Added caching to the getItems method for Feeds. |
439 |
"""Create the list of items.
|
440 |
||
441 |
Called by getItems which may cache the results.
|
|
442 |
"""
|
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
443 |
items = self._getRawItems() |
444 |
# Convert the items into their feed entry representation.
|
|
445 |
items = [self.itemToFeedEntry(item) for item in items] |
|
446 |
return items |
|
447 |
||
448 |
def itemToFeedEntry(self, rev): |
|
449 |
"""See `IFeed`."""
|
|
450 |
title = FeedTypedData("Revision %d" % rev.sequence) |
|
7622.1.2
by Michael Hudson
some progress |
451 |
url = self.context.codebrowse_url('revision', str(rev.sequence)) |
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
452 |
content_view = BranchFeedContentView(rev, self.request, self, |
453 |
'templates/branch-revision.pt') |
|
454 |
content = FeedTypedData(content=content_view.render(), |
|
5204.6.35
by Brad Crittenden
Correct relative hrefs in feeds. Removed duplicate branch entries. |
455 |
content_type="html", |
456 |
root_url=self.root_url) |
|
5204.6.27
by Brad Crittenden
Added tests for single branch feed. |
457 |
entry = BranchFeedEntry( |
458 |
title=title, |
|
459 |
link_alternate=url, |
|
460 |
date_created=rev.revision.date_created, |
|
461 |
date_updated=rev.revision.revision_date, |
|
462 |
date_published=None, |
|
463 |
authors=[RevisionPerson( |
|
464 |
rev.revision.revision_author, |
|
465 |
self.rootsite)], |
|
466 |
content=content) |
|
5204.6.26
by Brad Crittenden
Added feed for latest revisions on a given branch. |
467 |
return entry |