14642.1.8
by Curtis Hovey
Updated copyright. |
1 |
# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
|
8687.15.15
by Karl Fogel
Add the copyright header block to files under lib/lp/bugs/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
2071
by Canonical.com Patch Queue Manager
[trivial] add more __all__ statements, other minor tidyings-up |
4 |
"""Bug attachment views."""
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
__all__ = [ |
|
10104.4.2
by Abel Deuring
implemented reviewer's comments |
8 |
'BugAttachmentContentCheck', |
11235.6.1
by Abel Deuring
navigation class added that allows to access Librarian files of bug attachments vir ProxiedLibraryFileAlias; some lint fixes. |
9 |
'BugAttachmentFileNavigation', |
2628
by Canonical.com Patch Queue Manager
[trivial] converted a bunch of browser:traverse into navigation |
10 |
'BugAttachmentSetNavigation', |
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
11 |
'BugAttachmentEditView', |
6887.5.14
by Gavin Panella
Use urldata to define the browser URL for a bug attachment. |
12 |
'BugAttachmentURL', |
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
13 |
]
|
2238
by Canonical.com Patch Queue Manager
[r=jamesh] initial support for bug attachments. still some tweaks needed before the implementation fully matches the spec. |
14 |
|
13931.2.1
by Steve Kowalik
Chip away at canonical.lazr a little more. |
15 |
from lazr.restful.utils import smartquote |
11538.4.1
by Abel Deuring
more efficent change of the content type of bug attachments |
16 |
from zope.component import ( |
17 |
getMultiAdapter, |
|
18 |
getUtility, |
|
19 |
)
|
|
10104.4.1
by Abel Deuring
Fix for bug 172501: reject non-code patch attachements |
20 |
from zope.contenttype import guess_content_type |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
21 |
from zope.interface import implements |
2238
by Canonical.com Patch Queue Manager
[r=jamesh] initial support for bug attachments. still some tweaks needed before the implementation fully matches the spec. |
22 |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
23 |
from lp.app.browser.launchpadform import ( |
24 |
action, |
|
14642.1.3
by Curtis Hovey
Removed custom_widget from webapp glob. |
25 |
custom_widget, |
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
26 |
LaunchpadFormView, |
27 |
)
|
|
12293.1.10
by Curtis Hovey
Formatted imports. |
28 |
from lp.app.widgets.itemswidgets import LaunchpadBooleanRadioWidget |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
29 |
from lp.bugs.interfaces.bugattachment import ( |
30 |
BugAttachmentType, |
|
31 |
IBugAttachment, |
|
32 |
IBugAttachmentEditForm, |
|
33 |
IBugAttachmentIsPatchConfirmationForm, |
|
34 |
IBugAttachmentSet, |
|
35 |
)
|
|
14578.2.1
by William Grant
Move librarian stuff from canonical.launchpad to lp.services.librarian. canonical.librarian remains untouched. |
36 |
from lp.services.librarian.browser import ( |
37 |
FileNavigationMixin, |
|
38 |
ProxiedLibraryFileAlias, |
|
39 |
)
|
|
40 |
from lp.services.librarian.interfaces import ILibraryFileAliasWithParent |
|
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
41 |
from lp.services.webapp import ( |
42 |
canonical_url, |
|
43 |
GetitemNavigation, |
|
44 |
Navigation, |
|
45 |
)
|
|
46 |
from lp.services.webapp.interfaces import ( |
|
47 |
ICanonicalUrlData, |
|
48 |
ILaunchBag, |
|
49 |
)
|
|
50 |
from lp.services.webapp.menu import structured |
|
11235.6.1
by Abel Deuring
navigation class added that allows to access Librarian files of bug attachments vir ProxiedLibraryFileAlias; some lint fixes. |
51 |
|
2628
by Canonical.com Patch Queue Manager
[trivial] converted a bunch of browser:traverse into navigation |
52 |
|
10104.4.2
by Abel Deuring
implemented reviewer's comments |
53 |
class BugAttachmentContentCheck: |
54 |
"""A mixin class that checks the consistency of patch flag and file type.
|
|
55 |
"""
|
|
56 |
||
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
57 |
def guessContentType(self, filename, file_content): |
10542.13.3
by Karl Fogel
Start on fix for bug #538219 ("debdiff does not look like a patch"): |
58 |
"""Guess the content type a file with the given name and content."""
|
10104.4.2
by Abel Deuring
implemented reviewer's comments |
59 |
guessed_type, encoding = guess_content_type( |
60 |
name=filename, body=file_content) |
|
10542.13.3
by Karl Fogel
Start on fix for bug #538219 ("debdiff does not look like a patch"): |
61 |
# Zope's guess_content_type() doesn't consider all the factors
|
62 |
# we want considered. So after we get its answer, we probe a
|
|
10542.13.5
by Karl Fogel
Finish bug #538219 ("debdiff does not look like a patch"): |
63 |
# little further. But we still don't look at the encoding nor
|
64 |
# the file content, because we'd like to avoid reimplementing
|
|
65 |
# 'patch'. See bug #538219 for more.
|
|
10542.13.3
by Karl Fogel
Start on fix for bug #538219 ("debdiff does not look like a patch"): |
66 |
if (guessed_type == 'text/plain' |
10542.13.5
by Karl Fogel
Finish bug #538219 ("debdiff does not look like a patch"): |
67 |
and (filename.endswith('.diff') |
68 |
or filename.endswith('.debdiff') |
|
69 |
or filename.endswith('.patch'))): |
|
10542.13.3
by Karl Fogel
Start on fix for bug #538219 ("debdiff does not look like a patch"): |
70 |
guessed_type = 'text/x-diff' |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
71 |
return guessed_type |
72 |
||
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
73 |
def attachmentTypeConsistentWithContentType( |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
74 |
self, patch_flag_set, filename, file_content): |
75 |
"""Return True iff patch_flag is consistent with filename and content.
|
|
76 |
"""
|
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
77 |
guessed_type = self.guessContentType(filename, file_content) |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
78 |
# An XOR of "is the patch flag selected?" with "is the
|
79 |
# guessed type not a diff?" tells us if the type selected
|
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
80 |
# by the user matches the guessed type.
|
10104.4.2
by Abel Deuring
implemented reviewer's comments |
81 |
return (patch_flag_set ^ (guessed_type != 'text/x-diff')) |
82 |
||
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
83 |
def nextUrlForInconsistentPatchFlags(self, attachment): |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
84 |
"""The next_url value used for an inconistent patch flag."""
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
85 |
return canonical_url(attachment) + '/+confirm-is-patch' |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
86 |
|
87 |
||
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
88 |
class BugAttachmentSetNavigation(GetitemNavigation): |
2628
by Canonical.com Patch Queue Manager
[trivial] converted a bunch of browser:traverse into navigation |
89 |
|
90 |
usedfor = IBugAttachmentSet |
|
91 |
||
92 |
||
12736.8.4
by William Grant
Add warning comment to BugAttachmentURL. It's not very canonical. |
93 |
# Despite declaring compliance with ICanonicalUrlData, the LaunchBag
|
94 |
# dependency means this tends towards the "not canonical at all" end of
|
|
95 |
# the canonicalness scale. Beware.
|
|
6887.5.14
by Gavin Panella
Use urldata to define the browser URL for a bug attachment. |
96 |
class BugAttachmentURL: |
97 |
"""Bug URL creation rules."""
|
|
98 |
implements(ICanonicalUrlData) |
|
99 |
||
100 |
rootsite = 'bugs' |
|
101 |
||
102 |
def __init__(self, context): |
|
103 |
self.context = context |
|
104 |
||
105 |
@property
|
|
106 |
def inside(self): |
|
6887.5.18
by Gavin Panella
Default to a bug context when no bugtask has been traversed. |
107 |
"""Always relative to a traversed bugtask."""
|
6887.5.14
by Gavin Panella
Use urldata to define the browser URL for a bug attachment. |
108 |
bugtask = getUtility(ILaunchBag).bugtask |
109 |
if bugtask is None: |
|
6887.5.18
by Gavin Panella
Default to a bug context when no bugtask has been traversed. |
110 |
return self.context.bug |
6887.5.14
by Gavin Panella
Use urldata to define the browser URL for a bug attachment. |
111 |
else: |
112 |
return bugtask |
|
113 |
||
114 |
@property
|
|
115 |
def path(self): |
|
116 |
"""Return the path component of the URL."""
|
|
117 |
return u"+attachment/%d" % self.context.id |
|
118 |
||
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
119 |
|
10104.4.2
by Abel Deuring
implemented reviewer's comments |
120 |
class BugAttachmentEditView(LaunchpadFormView, BugAttachmentContentCheck): |
3854.1.4
by Bjorn Tillenius
add docstrings. |
121 |
"""Edit a bug attachment."""
|
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
122 |
|
123 |
schema = IBugAttachmentEditForm |
|
124 |
field_names = ['title', 'patch', 'contenttype'] |
|
125 |
||
126 |
def __init__(self, context, request): |
|
127 |
LaunchpadFormView.__init__(self, context, request) |
|
6887.5.18
by Gavin Panella
Default to a bug context when no bugtask has been traversed. |
128 |
self.next_url = self.cancel_url = ( |
129 |
canonical_url(ICanonicalUrlData(context).inside)) |
|
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
130 |
|
131 |
@property
|
|
132 |
def initial_values(self): |
|
133 |
attachment = self.context |
|
134 |
return dict( |
|
135 |
title=attachment.title, |
|
136 |
patch=attachment.type == BugAttachmentType.PATCH, |
|
137 |
contenttype=attachment.libraryfile.mimetype) |
|
138 |
||
139 |
@action('Change', name='change') |
|
140 |
def change_action(self, action, data): |
|
141 |
if data['patch']: |
|
142 |
new_type = BugAttachmentType.PATCH |
|
143 |
else: |
|
3854.1.8
by Bjorn Tillenius
review comments. |
144 |
new_type = BugAttachmentType.UNSPECIFIED |
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
145 |
if new_type != self.context.type: |
10104.4.1
by Abel Deuring
Fix for bug 172501: reject non-code patch attachements |
146 |
filename = self.context.libraryfile.filename |
147 |
file_content = self.context.libraryfile.read() |
|
148 |
# We expect that users set data['patch'] to True only for
|
|
149 |
# real patch data, indicated by guessed_content_type ==
|
|
150 |
# 'text/x-diff'. If there are inconsistencies, we don't
|
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
151 |
# set the value automatically. Instead, we lead the user to
|
152 |
# another form where we ask him if he is sure about his
|
|
153 |
# choice of the patch flag.
|
|
10104.4.1
by Abel Deuring
Fix for bug 172501: reject non-code patch attachements |
154 |
new_type_consistent_with_guessed_type = ( |
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
155 |
self.attachmentTypeConsistentWithContentType( |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
156 |
new_type == BugAttachmentType.PATCH, filename, |
157 |
file_content)) |
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
158 |
if new_type_consistent_with_guessed_type: |
10104.4.1
by Abel Deuring
Fix for bug 172501: reject non-code patch attachements |
159 |
self.context.type = new_type |
160 |
else: |
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
161 |
self.next_url = self.nextUrlForInconsistentPatchFlags( |
10104.4.2
by Abel Deuring
implemented reviewer's comments |
162 |
self.context) |
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
163 |
|
164 |
if data['title'] != self.context.title: |
|
165 |
self.context.title = data['title'] |
|
166 |
||
167 |
if self.context.libraryfile.mimetype != data['contenttype']: |
|
11538.4.1
by Abel Deuring
more efficent change of the content type of bug attachments |
168 |
lfa_with_parent = getMultiAdapter( |
169 |
(self.context.libraryfile, self.context), |
|
170 |
ILibraryFileAliasWithParent) |
|
171 |
lfa_with_parent.mimetype = data['contenttype'] |
|
3854.1.2
by Bjorn Tillenius
make the bug attachment edit view into a LaunchpadFormView. |
172 |
|
6036.2.1
by Abel Deuring
Fix for bugs 182282 and 182289 |
173 |
@action('Delete Attachment', name='delete') |
3854.1.3
by Bjorn Tillenius
add ui for deleting a bug attachment. |
174 |
def delete_action(self, action, data): |
11235.8.4
by Abel Deuring
change the bug attachment download URL shown in a otification when an attachment is deleted. |
175 |
libraryfile_url = ProxiedLibraryFileAlias( |
176 |
self.context.libraryfile, self.context).http_url |
|
5594.1.9
by Maris Fogels
Fixed all of the calls to addInfoNotification() that contain HTML so that they use the structured() class. Also fixed a number of broken uses of the _() translation function. |
177 |
self.request.response.addInfoNotification(structured( |
7675.415.9
by Abel Deuring
implemented reviewer's comments |
178 |
'Attachment "<a href="%(url)s">%(name)s</a>" has been deleted.', |
11235.8.4
by Abel Deuring
change the bug attachment download URL shown in a otification when an attachment is deleted. |
179 |
url=libraryfile_url, name=self.context.title)) |
7947.5.7
by Graham Binns
Merged changes from attachments branch. |
180 |
self.context.removeFromBug(user=self.user) |
3854.1.3
by Bjorn Tillenius
add ui for deleting a bug attachment. |
181 |
|
9270.1.2
by Abel Deuring
changed page title and form label |
182 |
@property
|
183 |
def label(self): |
|
14433.2.29
by Curtis Hovey
Make labels look like other page headings. |
184 |
return smartquote('Edit attachment "%s"') % self.context.title |
9270.1.2
by Abel Deuring
changed page title and form label |
185 |
|
14433.2.28
by Curtis Hovey
Removed the redundant 'bug #nnnnnn -' from page_titles and breadcrumbs. |
186 |
page_title = 'Edit attachment' |
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
187 |
|
188 |
||
189 |
class BugAttachmentPatchConfirmationView(LaunchpadFormView): |
|
190 |
"""Confirmation of the "patch" flag setting.
|
|
191 |
||
192 |
If the user sets the "patch" flag to a value that is inconsistent
|
|
193 |
with the result of a call of guess_content_type() for this
|
|
194 |
attachment, we show this view to ask the user if he is sure
|
|
195 |
about his selection.
|
|
196 |
"""
|
|
197 |
||
198 |
schema = IBugAttachmentIsPatchConfirmationForm |
|
199 |
||
200 |
custom_widget('patch', LaunchpadBooleanRadioWidget) |
|
201 |
||
202 |
def __init__(self, context, request): |
|
203 |
LaunchpadFormView.__init__(self, context, request) |
|
204 |
self.next_url = self.cancel_url = ( |
|
205 |
canonical_url(ICanonicalUrlData(context).inside)) |
|
206 |
||
207 |
def initialize(self): |
|
208 |
super(BugAttachmentPatchConfirmationView, self).initialize() |
|
209 |
self.widgets['patch'].setRenderedValue(self.is_patch) |
|
210 |
||
211 |
@property
|
|
212 |
def label(self): |
|
14433.2.29
by Curtis Hovey
Make labels look like other page headings. |
213 |
return smartquote('Confirm attachment type of "%s"') % ( |
214 |
self.context.title) |
|
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
215 |
|
14433.2.28
by Curtis Hovey
Removed the redundant 'bug #nnnnnn -' from page_titles and breadcrumbs. |
216 |
page_title = 'Confirm attachment type' |
10104.4.4
by Abel Deuring
new view +confirm-is-patch shown when a bugattachment is added or when the patch flag of an existing attachment is changed and when LP treats the patch flag setting by the user as possibly wrong. |
217 |
|
218 |
@action('Change', name='change') |
|
219 |
def change_action(self, action, data): |
|
220 |
current_patch_setting = self.context.type == BugAttachmentType.PATCH |
|
221 |
if data['patch'] != current_patch_setting: |
|
222 |
if data['patch']: |
|
223 |
self.context.type = BugAttachmentType.PATCH |
|
224 |
#xxxxxxxxxx adjust content type!
|
|
225 |
# xxx use mixin, together with BugAttachmnetEditView
|
|
226 |
else: |
|
227 |
self.context.type = BugAttachmentType.UNSPECIFIED |
|
10104.4.1
by Abel Deuring
Fix for bug 172501: reject non-code patch attachements |
228 |
|
229 |
@property
|
|
230 |
def is_patch(self): |
|
231 |
"""True if this attachment contains a patch, else False."""
|
|
232 |
return self.context.type == BugAttachmentType.PATCH |
|
11235.6.1
by Abel Deuring
navigation class added that allows to access Librarian files of bug attachments vir ProxiedLibraryFileAlias; some lint fixes. |
233 |
|
234 |
||
235 |
class BugAttachmentFileNavigation(Navigation, FileNavigationMixin): |
|
236 |
"""Traversal to +files/${filename}."""
|
|
237 |
||
238 |
usedfor = IBugAttachment |