Merge lp:~adeuring/launchpad/bug-39674-change-remaining-lfa-http_url into lp:launchpad/db-devel

Proposed by Abel Deuring
Status: Merged
Merged at revision: 9619
Proposed branch: lp:~adeuring/launchpad/bug-39674-change-remaining-lfa-http_url
Merge into: lp:launchpad/db-devel
Diff against target: 514 lines (+105/-48)
17 files modified
lib/canonical/launchpad/browser/librarian.py (+4/-2)
lib/canonical/launchpad/webapp/launchbag.py (+1/-1)
lib/canonical/librarian/client.py (+1/-0)
lib/lp/bugs/adapters/bugchange.py (+13/-4)
lib/lp/bugs/browser/bug.py (+8/-1)
lib/lp/bugs/browser/bugattachment.py (+4/-2)
lib/lp/bugs/browser/bugtarget.py (+5/-0)
lib/lp/bugs/doc/bug-change.txt (+6/-4)
lib/lp/bugs/doc/bug-export.txt (+1/-1)
lib/lp/bugs/doc/bugnotification-email.txt (+10/-20)
lib/lp/bugs/model/bugattachment.py (+5/-0)
lib/lp/bugs/scripts/bugexport.py (+3/-1)
lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt (+5/-1)
lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt (+3/-1)
lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt (+24/-5)
lib/lp/bugs/templates/bugtarget-patches.pt (+2/-2)
lib/lp/bugs/tests/test_bugchanges.py (+10/-3)
To merge this branch: bzr merge lp:~adeuring/launchpad/bug-39674-change-remaining-lfa-http_url
Reviewer Review Type Date Requested Status
Deryck Hodge (community) code Approve
Review via email: mp+31754@code.launchpad.net

Description of the change

This branch changes the URLs of LFAs of bug attachments shown in
some web pages and notification emails from LFA.http_url to
ProxiedLibraryFileAlias.http_url and fixes some related issues.

lib/canonical/launchpad/browser/librarian.py:

The URLs created by ProxiedLibraryFileAlias.http_url were not properly
escaped; non-ASCII-characters in file names caused exceptions, for example
in lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt

I copied the pattern to generate URLs from LFA.http_url resp.
FileDownloadClient.getURLForAlias().

lib/canonical/launchpad/webapp/launchbag.py:

Some tests failed because canonical_url(bug_attachment) wants to access
launchbag.bugtask, but this property is not defined for a freshly created
launchbag.

lib/canonical/librarian/client.py:

The function quote() is now also used in ProxiedLibraryFileAlias.http_url,
so it should appear in __all__.

lib/lp/bugs/adapters/bugchange.py:

The data generated by class BugAttachmentChange when an attachment
is created or deleted now contains URLs from ProxiedLFAs.

lib/lp/bugs/browser/bug.py:

class BugView has a new method proxiedUrlForLibraryFile(). This method
is called from at least one page template. (Sorry, can't remember
which template is it -- this branch contains too many small changes...)

BugTextView.attachment_text() uses proxied LFA URLs.

lib/lp/bugs/browser/bugattachment.py:

BugAttachmentEditView.delete_action shows proxied LFA URLs in a notification.

lib/lp/bugs/browser/bugtarget.py:

A new helper method to get proxied LFA URLs in class BugsPatchesView,
similar to that ini class BugView.

lib/lp/bugs/model/bugattachment.py:

When notifications about a new bug attachment are created,
canonical_url(new_attachment) is called; this function needs the
bug attachment ID, and this ID is not available if the DB record
is not yet created. Hence the Store.of(attachment).flush() call.

The remaining changes are in tests which are affected by the changed
URLs. The test lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt
now looks quite ugly in line 197ff: The download URLs now start with
regular bug URLs, i.e., we can access the LFAs via

http://bugs.launchpad.dev/bugs/1/+attachment/1/+files/file_a.txt

as well as

http://bugs.launchpad.dev/firefox/+bug/1/+attachment/1/+files/file_a.txt

Which URL is created, depends on the existence of a bugtask in LaunchBag.

This is a bit silly for the file content, but I simply did not have enough
time to fix it, and I'd like to really make bug attachments private
for private bugs in the next release...

tests: many. All those which I touched...

To post a comment you must log in.
Revision history for this message
Deryck Hodge (deryck) wrote :

The changes generally look good, Abel. Thanks for all the work you've been doing to get this ready!

I have two minor requests:

1) If there are bugs for these related issues that are fixed, can you link the branch to them so they get marked fixed when this lands?

2) Can you add a comment in code explaining why the flush is required?

Consider this r=me with these minor changes.

Cheers,
deryck

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/browser/librarian.py'
2--- lib/canonical/launchpad/browser/librarian.py 2010-08-03 13:37:55 +0000
3+++ lib/canonical/launchpad/browser/librarian.py 2010-08-04 15:48:48 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2009 Canonical Ltd. This software is licensed under the
6+# Copyright 2010 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """Browser file for LibraryFileAlias."""
10@@ -32,6 +32,7 @@
11 IWebBrowserOriginatingRequest)
12 from canonical.launchpad.webapp.url import urlappend
13 from canonical.lazr.utils import get_current_browser_request
14+from canonical.librarian.client import quote
15 from canonical.librarian.interfaces import LibrarianServerError
16 from canonical.librarian.utils import filechunks, guess_librarian_encoding
17
18@@ -220,5 +221,6 @@
19
20 parent_url = canonical_url(self.parent, request=request)
21 traversal_url = urlappend(parent_url, '+files')
22- url = urlappend(traversal_url, self.context.filename)
23+ url = urlappend(
24+ traversal_url, quote(self.context.filename.encode('utf-8')))
25 return url
26
27=== modified file 'lib/canonical/launchpad/webapp/launchbag.py'
28--- lib/canonical/launchpad/webapp/launchbag.py 2010-07-30 00:06:00 +0000
29+++ lib/canonical/launchpad/webapp/launchbag.py 2010-08-04 15:48:48 +0000
30@@ -136,7 +136,7 @@
31
32 @property
33 def bugtask(self):
34- return self._store.bugtask
35+ return getattr(self._store, "bugtask", None)
36
37 @property
38 def time_zone(self):
39
40=== modified file 'lib/canonical/librarian/client.py'
41--- lib/canonical/librarian/client.py 2010-03-25 20:03:55 +0000
42+++ lib/canonical/librarian/client.py 2010-08-04 15:48:48 +0000
43@@ -8,6 +8,7 @@
44 'FileUploadClient',
45 'LibrarianClient',
46 'RestrictedLibrarianClient',
47+ 'quote',
48 ]
49
50
51
52=== modified file 'lib/lp/bugs/adapters/bugchange.py'
53--- lib/lp/bugs/adapters/bugchange.py 2010-06-09 16:24:23 +0000
54+++ lib/lp/bugs/adapters/bugchange.py 2010-08-04 15:48:48 +0000
55@@ -38,6 +38,7 @@
56 from lp.bugs.interfaces.bugchange import IBugChange
57 from lp.bugs.interfaces.bugtask import IBugTask
58 from lp.registry.interfaces.product import IProduct
59+from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
60 from canonical.launchpad.webapp.publisher import canonical_url
61
62
63@@ -527,6 +528,12 @@
64 return {'text': "\n".join(messages)}
65
66
67+def download_url_of_bugattachment(attachment):
68+ """Return the URL of the ProxiedLibraryFileAlias for the attachment."""
69+ return ProxiedLibraryFileAlias(
70+ attachment.libraryfile, attachment).http_url
71+
72+
73 class BugAttachmentChange(AttributeChange):
74 """Used to represent a change to an `IBug`'s attachments."""
75
76@@ -535,12 +542,14 @@
77 what_changed = "attachment added"
78 old_value = None
79 new_value = "%s %s" % (
80- self.new_value.title, self.new_value.libraryfile.http_url)
81+ self.new_value.title,
82+ download_url_of_bugattachment(self.new_value))
83 else:
84 what_changed = "attachment removed"
85 attachment = self.new_value
86 old_value = "%s %s" % (
87- self.old_value.title, self.old_value.libraryfile.http_url)
88+ self.old_value.title,
89+ download_url_of_bugattachment(self.old_value))
90 new_value = None
91
92 return {
93@@ -557,7 +566,7 @@
94 attachment_str = 'Attachment'
95 message = '** %s added: "%s"\n %s' % (
96 attachment_str, self.new_value.title,
97- self.new_value.libraryfile.http_url)
98+ download_url_of_bugattachment(self.new_value))
99 else:
100 if self.old_value.is_patch:
101 attachment_str = 'Patch'
102@@ -565,7 +574,7 @@
103 attachment_str = 'Attachment'
104 message = '** %s removed: "%s"\n %s' % (
105 attachment_str, self.old_value.title,
106- self.old_value.libraryfile.http_url)
107+ download_url_of_bugattachment(self.old_value))
108
109 return {'text': message}
110
111
112=== modified file 'lib/lp/bugs/browser/bug.py'
113--- lib/lp/bugs/browser/bug.py 2010-08-03 08:49:19 +0000
114+++ lib/lp/bugs/browser/bug.py 2010-08-04 15:48:48 +0000
115@@ -557,6 +557,11 @@
116
117 return dupes
118
119+ def proxiedUrlForLibraryFile(self, attachment):
120+ """Return the proxied download URL for a Librarian file."""
121+ return ProxiedLibraryFileAlias(
122+ attachment.libraryfile, attachment).http_url
123+
124
125 class BugWithoutContextView:
126 """View that redirects to the new bug page.
127@@ -870,7 +875,9 @@
128 """Return a text representation of a bug attachment."""
129 mime_type = normalize_mime_type.sub(
130 ' ', attachment.libraryfile.mimetype)
131- return "%s %s" % (attachment.libraryfile.http_url, mime_type)
132+ download_url = ProxiedLibraryFileAlias(
133+ attachment.libraryfile, attachment).http_url
134+ return "%s %s" % (download_url, mime_type)
135
136 def comment_text(self):
137 """Return a text representation of bug comments."""
138
139=== modified file 'lib/lp/bugs/browser/bugattachment.py'
140--- lib/lp/bugs/browser/bugattachment.py 2010-08-03 13:37:55 +0000
141+++ lib/lp/bugs/browser/bugattachment.py 2010-08-04 15:48:48 +0000
142@@ -20,7 +20,7 @@
143 from zope.contenttype import guess_content_type
144
145 from canonical.launchpad.browser.librarian import (
146- FileNavigationMixin, StreamOrRedirectLibraryFileAliasView)
147+ FileNavigationMixin, ProxiedLibraryFileAlias, StreamOrRedirectLibraryFileAliasView)
148 from canonical.launchpad.webapp import (
149 canonical_url, custom_widget, GetitemNavigation, Navigation)
150 from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
151@@ -156,9 +156,11 @@
152
153 @action('Delete Attachment', name='delete')
154 def delete_action(self, action, data):
155+ libraryfile_url = ProxiedLibraryFileAlias(
156+ self.context.libraryfile, self.context).http_url
157 self.request.response.addInfoNotification(structured(
158 'Attachment "<a href="%(url)s">%(name)s</a>" has been deleted.',
159- url=self.context.libraryfile.http_url, name=self.context.title))
160+ url=libraryfile_url, name=self.context.title))
161 self.context.removeFromBug(user=self.user)
162
163 def updateContentType(self, new_content_type):
164
165=== modified file 'lib/lp/bugs/browser/bugtarget.py'
166--- lib/lp/bugs/browser/bugtarget.py 2010-08-02 02:13:52 +0000
167+++ lib/lp/bugs/browser/bugtarget.py 2010-08-04 15:48:48 +0000
168@@ -57,6 +57,7 @@
169 from canonical.launchpad import _
170 from canonical.launchpad.browser.feeds import (
171 BugFeedLink, BugTargetLatestBugsFeedLink, FeedsMixin)
172+from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
173 from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
174 from lp.bugs.interfaces.bugtarget import (
175 IBugTarget, IOfficialBugTagTargetPublic, IOfficialBugTagTargetRestricted)
176@@ -1469,3 +1470,7 @@
177 """Return a timedelta object for the age of a patch attachment."""
178 now = datetime.now(timezone('UTC'))
179 return now - patch.message.datecreated
180+
181+ def proxiedUrlForLibraryFile(self, patch):
182+ """Return the proxied download URL for a Librarian file."""
183+ return ProxiedLibraryFileAlias(patch.libraryfile, patch).http_url
184
185=== modified file 'lib/lp/bugs/doc/bug-change.txt'
186--- lib/lp/bugs/doc/bug-change.txt 2010-06-16 08:27:19 +0000
187+++ lib/lp/bugs/doc/bug-change.txt 2010-08-04 15:48:48 +0000
188@@ -479,13 +479,14 @@
189 ... old_value=None, new_value=attachment)
190
191 >>> print pretty(attachment_change.getBugActivity())
192- {'newvalue': u'sample-attachment http://...',
193+ {'newvalue':
194+ u'sample-attachment http://bugs.launchpad.dev/bugs/...+files/...',
195 'oldvalue': None,
196 'whatchanged': 'attachment added'}
197
198 >>> print attachment_change.getBugNotification()['text']
199 ** Attachment added: "sample-attachment"
200- http...
201+ http://bugs.launchpad.dev/bugs/.../+attachment/1/+files/...
202
203 Or remove one.
204
205@@ -496,12 +497,13 @@
206
207 >>> print pretty(attachment_change.getBugActivity())
208 {'newvalue': None,
209- 'oldvalue': u'sample-attachment http://...',
210+ 'oldvalue':
211+ u'sample-attachment http://bugs.launchpad.dev/bugs/...+files/...',
212 'whatchanged': 'attachment removed'}
213
214 >>> print attachment_change.getBugNotification()['text']
215 ** Attachment removed: "sample-attachment"
216- http...
217+ http://bugs.launchpad.dev/bugs/.../+attachment/1/+files/...
218
219
220 == BugTaskAttributeChange ==
221
222=== modified file 'lib/lp/bugs/doc/bug-export.txt'
223--- lib/lp/bugs/doc/bug-export.txt 2009-09-04 10:43:39 +0000
224+++ lib/lp/bugs/doc/bug-export.txt 2010-08-04 15:48:48 +0000
225@@ -141,7 +141,7 @@
226 <sender name="name12">Sample Person</sender>
227 <date>...</date>
228 <text>Added attachment</text>
229- <attachment href="http://localhost:58000/.../hello.txt">
230+ <attachment href="http://bugs.launchpad.dev/bugs/1/.../+files/hello.txt">
231 <type>UNSPECIFIED</type>
232 <filename>hello.txt</filename>
233 <title>"Hello World" attachment</title>
234
235=== modified file 'lib/lp/bugs/doc/bugnotification-email.txt'
236--- lib/lp/bugs/doc/bugnotification-email.txt 2010-07-28 22:33:59 +0000
237+++ lib/lp/bugs/doc/bugnotification-email.txt 2010-08-04 15:48:48 +0000
238@@ -343,18 +343,9 @@
239
240 Adding an attachment will generate a notification that looks as follows:
241
242- >>> class MockLibraryFile:
243- ... def __init__(self, url):
244- ... self.http_url = url
245- >>> class MockAttachment:
246- ... def __init__(self, title, libraryfile, is_patch=False):
247- ... self.title = title
248- ... self.libraryfile = libraryfile
249- ... self.is_patch = is_patch
250- >>> attachment = MockAttachment(
251- ... title="A screenshot of the problem",
252- ... libraryfile=MockLibraryFile('http://foo.com/screenshot.png'))
253-
254+ >>> attachment = factory.makeBugAttachment(
255+ ... description="A screenshot of the problem",
256+ ... filename='screenshot.png')
257 >>> bug_delta = BugDelta(
258 ... bug=edited_bug,
259 ... bugurl="http://www.example.com/bugs/2",
260@@ -365,7 +356,7 @@
261 ... print notification['text'] #doctest: -NORMALIZE_WHITESPACE
262 ... print "-----------------------------"
263 ** Attachment added: "A screenshot of the problem"
264- http://foo.com/screenshot.png
265+ http://bugs.launchpad.dev/bugs/.../+attachment/1/+files/screenshot.png
266 -----------------------------
267
268 Removing an attachment generates a notification, too.
269@@ -380,16 +371,15 @@
270 ... print notification['text'] #doctest: -NORMALIZE_WHITESPACE
271 ... print "-----------------------------"
272 ** Attachment removed: "A screenshot of the problem"
273- http://foo.com/screenshot.png
274+ http://bugs.launchpad.dev/bugs/.../+attachment/1/+files/screenshot.png
275 -----------------------------
276
277 Adding an attachment and marking it as a patch generates a different
278 notification.
279
280- >>> attachment = MockAttachment(
281- ... title="A new icon for the application",
282- ... libraryfile=MockLibraryFile('http://foo.com/new-icon.png'),
283- ... is_patch=True)
284+ >>> attachment = factory.makeBugAttachment(
285+ ... description="A new icon for the application",
286+ ... filename='new-icon.png', is_patch=True)
287 >>> bug_delta = BugDelta(
288 ... bug=edited_bug,
289 ... bugurl="http://www.example.com/bugs/2",
290@@ -400,7 +390,7 @@
291 ... print notification['text'] #doctest: -NORMALIZE_WHITESPACE
292 ... print "-----------------------------"
293 ** Patch added: "A new icon for the application"
294- http://foo.com/new-icon.png
295+ http://bugs.launchpad.dev/bugs/.../+attachment/2/+files/new-icon.png
296 -----------------------------
297
298 Removing a patch also generates a different notification.
299@@ -415,7 +405,7 @@
300 ... print notification['text'] #doctest: -NORMALIZE_WHITESPACE
301 ... print "-----------------------------"
302 ** Patch removed: "A new icon for the application"
303- http://foo.com/new-icon.png
304+ http://bugs.launchpad.dev/bugs/.../+attachment/2/+files/new-icon.png
305 -----------------------------
306
307
308
309=== modified file 'lib/lp/bugs/model/bugattachment.py'
310--- lib/lp/bugs/model/bugattachment.py 2010-08-03 08:49:19 +0000
311+++ lib/lp/bugs/model/bugattachment.py 2010-08-04 15:48:48 +0000
312@@ -12,6 +12,7 @@
313 from lazr.lifecycle.event import ObjectCreatedEvent, ObjectDeletedEvent
314
315 from sqlobject import ForeignKey, StringCol, SQLObjectNotFound
316+from storm.store import Store
317
318 from canonical.database.enumcol import EnumCol
319 from canonical.database.sqlbase import SQLBase
320@@ -92,6 +93,10 @@
321 attachment = BugAttachment(
322 bug=bug, libraryfile=filealias, type=attach_type, title=title,
323 message=message)
324+ # canonial_url(attachment) (called by notification subscribers
325+ # to generate the download URL of the attachments) blows up if
326+ # attachment.id is not (yet) set.
327+ Store.of(attachment).flush()
328 if send_notifications:
329 notify(ObjectCreatedEvent(attachment, user=message.owner))
330 return attachment
331
332=== modified file 'lib/lp/bugs/scripts/bugexport.py'
333--- lib/lp/bugs/scripts/bugexport.py 2009-09-04 10:43:39 +0000
334+++ lib/lp/bugs/scripts/bugexport.py 2010-08-04 15:48:48 +0000
335@@ -15,6 +15,7 @@
336
337 from zope.component import getUtility
338 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
339+from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
340 from lp.bugs.interfaces.bugtask import BugTaskSearchParams, IBugTaskSet
341 from lp.bugs.browser.bugtask import get_comments_for_bugtask
342
343@@ -80,7 +81,8 @@
344 for attachment in comment.bugattachments:
345 attachment_node = ET.SubElement(
346 comment_node, 'attachment',
347- href=attachment.libraryfile.http_url)
348+ href=ProxiedLibraryFileAlias(
349+ attachment.libraryfile, attachment).http_url)
350 attachment_node.text = attachment_node.tail = '\n'
351 addnode(attachment_node, 'type', attachment.type.name)
352 addnode(attachment_node, 'filename',
353
354=== modified file 'lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt'
355--- lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt 2010-07-29 11:20:47 +0000
356+++ lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt 2010-08-04 15:48:48 +0000
357@@ -23,8 +23,11 @@
358 >>> from zope.component import getUtility
359 >>> from canonical.launchpad.ftests import login, logout, syncUpdate
360 >>> from canonical.launchpad.interfaces import IBugSet
361+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
362 >>> login("test@canonical.com")
363- >>> bug_11 = getUtility(IBugSet).get(11)
364+ >>> bug_11 = getUtility(IBugSet).get(11)
365+ >>> launchbag = getUtility(ILaunchBag)
366+ >>> launchbag.clear()
367 >>> attachment = bug_11.addAttachment(
368 ... owner=None, data=StringIO.StringIO('whatever'),
369 ... comment=bug_11.initial_message, filename='test.txt',
370@@ -55,6 +58,7 @@
371 == Patch attachments are shown before non-patch attachments ==
372
373 >>> login("test@canonical.com")
374+ >>> launchbag.clear()
375 >>> patch_attachment = bug_11.addAttachment(
376 ... owner=None, data=StringIO.StringIO('patchy patch patch'),
377 ... comment=bug_11.initial_message, filename='patch.txt',
378
379=== modified file 'lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt'
380--- lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt 2010-07-29 11:20:47 +0000
381+++ lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt 2010-08-04 15:48:48 +0000
382@@ -51,7 +51,9 @@
383 'http://.../+bug/2'
384 >>> for message in find_tags_by_class(user_browser.contents, 'message'):
385 ... print message.renderContents()
386- Attachment "<a href="...">Great deal</a>" has been deleted.
387+ Attachment
388+ "<a href="http://bugs.launchpad.dev/...+files/foo.txt">Great deal</a>"
389+ has been deleted.
390
391 >>> print find_portlet(user_browser.contents, 'Bug attachments')
392 None
393
394=== modified file 'lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt'
395--- lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt 2010-06-25 13:34:37 +0000
396+++ lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt 2010-08-04 15:48:48 +0000
397@@ -70,8 +70,9 @@
398 duplicate-of:
399 duplicates:
400 attachments:
401- http://.../file_a.txt text/html
402- http://.../file%20with%20space.txt text/plain; name="file with space.txt"
403+ http://bugs.launchpad.dev/.../+files/file_a.txt text/html
404+ http://bugs.launchpad.dev/.../+files/file%20with%20space.txt
405+ text/plain; name="file with space.txt"
406 patches:
407 http://.../bug-patch.diff text/plain
408 tags:
409@@ -149,7 +150,7 @@
410 >>> attachments_text = text_bug[text_bug.find('attachments:'):]
411 >>> attachment_2 = attachments_text.split('\n')[2]
412 >>> attachment_2
413- ' http://localhost:58000/.../file%20with%20space.txt text/plain;
414+ ' http://bugs.launchpad.dev/.../file%20with%20space.txt text/plain;
415 name="file with space.txt"'
416
417
418@@ -196,11 +197,29 @@
419 >>> separator_bug = separator_regex.findall(text_bug)[0]
420 >>> separator_bug_task = separator_regex.findall(text_bug_task)[0]
421
422-Now we can show that the individual sections are identical for each report:
423+Now we can show that the individual sections are identical for each report.
424+The only differences are the download URLs of bug attachments:
425
426- >>> text_bug.split(separator_bug) == text_bug_task.split(separator_bug_task)
427+ >>> text_bug_chunks = text_bug.split(separator_bug)
428+ >>> text_bug_task_chunks = text_bug_task.split(separator_bug_task)
429+ >>> len(text_bug_chunks) == len(text_bug_task_chunks)
430 True
431
432+ >>> for chunk_no in range(len(text_bug_task_chunks)):
433+ ... if text_bug_task_chunks[chunk_no] != text_bug_chunks[chunk_no]:
434+ ... bug_task_lines = text_bug_task_chunks[chunk_no].split('\n')
435+ ... bug_lines = text_bug_chunks[chunk_no].split('\n')
436+ ... assert(len(bug_task_lines) == len(bug_lines))
437+ ... for line_no in range(len(bug_task_lines)):
438+ ... if bug_lines[line_no] != bug_task_lines[line_no]:
439+ ... print bug_lines[line_no]
440+ ... print bug_task_lines[line_no]
441+ http://bugs.launchpad.dev/bugs/1/+attachment/1/+files/file_a.txt text/html
442+ http://bugs.launchpad.dev/firefox/+bug/.../+files/file_a.txt text/html
443+ http://bugs.launchpad.dev/bugs/1/.../+files/file%20with%20space.txt...
444+ http://bugs.launchpad.dev/firefox/+bug/.../+files/file%20with%20space.txt...
445+ http://bugs.launchpad.dev/bugs/1/.../+files/bug-patch.diff text/plain
446+ http://bugs.launchpad.dev/firefox/+bug/.../+files/bug-patch.diff text/plain
447
448 == Duplicate Bugs ==
449
450
451=== modified file 'lib/lp/bugs/templates/bugtarget-patches.pt'
452--- lib/lp/bugs/templates/bugtarget-patches.pt 2010-02-24 06:17:33 +0000
453+++ lib/lp/bugs/templates/bugtarget-patches.pt 2010-08-04 15:48:48 +0000
454@@ -74,7 +74,7 @@
455 tal:define="patch patch_task/bug/latest_patch;
456 age python:view.patchAge(patch)"
457 tal:attributes="id string:patch-cell-${repeat/patch_task/index}">
458- <a tal:attributes="href patch/libraryfile/http_url"
459+ <a tal:attributes="href python:view.proxiedUrlForLibraryFile(patch)"
460 tal:content="age/fmt:approximateduration/use-digits"></a>
461 <div class="popupTitle"
462 tal:attributes="id string:patch-popup-${repeat/patch_task/index};">
463@@ -82,7 +82,7 @@
464 <strong>From:</strong>
465 <a tal:replace="structure submitter/fmt:link"></a><br/>
466 <strong>Link:</strong>
467- <a tal:attributes="href patch/libraryfile/http_url"
468+ <a tal:attributes="href python:view.proxiedUrlForLibraryFile(patch)"
469 tal:content="patch/libraryfile/filename"></a></p>
470 <p tal:content="string:${patch/title}"></p>
471 </div>
472
473=== modified file 'lib/lp/bugs/tests/test_bugchanges.py'
474--- lib/lp/bugs/tests/test_bugchanges.py 2010-07-22 12:17:41 +0000
475+++ lib/lp/bugs/tests/test_bugchanges.py 2010-08-04 15:48:48 +0000
476@@ -12,6 +12,7 @@
477 from lazr.lifecycle.event import ObjectCreatedEvent, ObjectModifiedEvent
478 from lazr.lifecycle.snapshot import Snapshot
479
480+from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
481 from canonical.launchpad.database import BugNotification
482 from canonical.launchpad.ftests import login
483 from lp.bugs.interfaces.bug import IBug
484@@ -686,13 +687,17 @@
485 'whatchanged': 'attachment added',
486 'oldvalue': None,
487 'newvalue': '%s %s' % (
488- attachment.title, attachment.libraryfile.http_url),
489+ attachment.title,
490+ ProxiedLibraryFileAlias(
491+ attachment.libraryfile, attachment).http_url),
492 }
493
494 attachment_added_notification = {
495 'person': self.user,
496 'text': '** Attachment added: "%s"\n %s' % (
497- attachment.title, attachment.libraryfile.http_url),
498+ attachment.title,
499+ ProxiedLibraryFileAlias(
500+ attachment.libraryfile, attachment).http_url),
501 }
502
503 self.assertRecordedChange(
504@@ -705,7 +710,9 @@
505 attachment = self.factory.makeBugAttachment(
506 bug=self.bug, owner=self.user)
507 self.saveOldChanges()
508- download_url = attachment.libraryfile.http_url
509+ download_url = ProxiedLibraryFileAlias(
510+ attachment.libraryfile, attachment).http_url
511+
512 attachment.removeFromBug(user=self.user)
513
514 attachment_removed_activity = {

Subscribers

People subscribed via source and target branches

to status/vote changes: