14557.1.20
by Curtis Hovey
Updated copyright. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.18
by Karl Fogel
Add the copyright header block to files under lib/canonical/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
3 |
|
4 |
__metaclass__ = type |
|
5 |
||
6 |
__all__ = [ |
|
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
7 |
'HWDBApplicationNavigation', |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
8 |
'HWDBFingerprintSetView', |
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
9 |
'HWDBPersonSubmissionsView', |
4912.1.1
by Christian Reis
Merge Abel's work, add a test for textual HWDB output, and make sure submission IDs are valid_names too. |
10 |
'HWDBSubmissionTextView', |
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
11 |
'HWDBUploadView', |
12 |
]
|
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
13 |
|
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
14 |
from textwrap import dedent |
15 |
||
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
16 |
from z3c.ptcompat import ViewPageTemplateFile |
8971.12.2
by Abel Deuring
implemented reviewr's comments |
17 |
from zope.component import getUtility |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
18 |
from zope.interface import implements |
19 |
from zope.publisher.interfaces.browser import IBrowserPublisher |
|
7849.16.64
by Sidnei da Silva
- Fix a couple problems found by Francis during review |
20 |
|
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
21 |
from lp.services.webapp import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
22 |
LaunchpadView, |
23 |
Navigation, |
|
24 |
stepthrough, |
|
25 |
)
|
|
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
26 |
from lp.services.webapp.interfaces import ILaunchBag |
27 |
from lp.services.webapp.batching import BatchNavigator |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
28 |
from lp.app.browser.launchpadform import ( |
29 |
action, |
|
30 |
LaunchpadFormView, |
|
31 |
)
|
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
32 |
from lp.app.errors import NotFoundError |
33 |
from lp.hardwaredb.interfaces.hwdb import ( |
|
34 |
IHWDBApplication, |
|
35 |
IHWDeviceClassSet, |
|
36 |
IHWDeviceSet, |
|
37 |
IHWDriverSet, |
|
38 |
IHWSubmissionDeviceSet, |
|
39 |
IHWSubmissionForm, |
|
40 |
IHWSubmissionSet, |
|
41 |
IHWSystemFingerprintSet, |
|
42 |
IHWVendorIDSet, |
|
43 |
)
|
|
44 |
from lp.registry.interfaces.distribution import IDistributionSet |
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
45 |
|
46 |
||
47 |
class HWDBUploadView(LaunchpadFormView): |
|
48 |
"""View class for hardware database submissions."""
|
|
49 |
||
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
50 |
schema = IHWSubmissionForm |
9521.2.1
by Gary Poster
handle the majority of the remaining launchpad templates for 3.0: remove 6 and change 6. Also remove another template bigjools requested removal for. |
51 |
label = 'Hardware Database Submission' |
52 |
page_title = 'Submit New Data to the Launchpad Hardware Database' |
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
53 |
|
54 |
@action(u'Upload', name='upload') |
|
55 |
def upload_action(self, action, data): |
|
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
56 |
"""Create a record in the HWSubmission table."""
|
8971.12.1
by Abel Deuring
fix for bug 357316: hwdb +submit failing with KeyError OOPS |
57 |
# We expect that the data submitted by the client contains
|
58 |
# data for all fields defined in the form. The main client
|
|
59 |
# which POSTs data to this URL, checkbox, sometimes omits
|
|
60 |
# some fields (see bug 357316). The absence of required
|
|
61 |
# fields is not caught by Zope's form validation -- it only
|
|
62 |
# checks if required fields are not empty, and does this only
|
|
63 |
# if these fields are present in the form data. Absent fields
|
|
64 |
# are not detected, so let's do that here.
|
|
65 |
expected_fields = set(self.schema.names()) |
|
8971.12.2
by Abel Deuring
implemented reviewr's comments |
66 |
submitted_fields = set(data) |
8971.12.1
by Abel Deuring
fix for bug 357316: hwdb +submit failing with KeyError OOPS |
67 |
missing_fields = expected_fields.difference(submitted_fields) |
68 |
if len(missing_fields) > 0: |
|
69 |
missing_fields = ', '.join(sorted(missing_fields)) |
|
70 |
self.addCustomHeader( |
|
8971.12.2
by Abel Deuring
implemented reviewr's comments |
71 |
'Error: Required fields not contained in POST data: '
|
8971.12.1
by Abel Deuring
fix for bug 357316: hwdb +submit failing with KeyError OOPS |
72 |
+ missing_fields) |
73 |
return
|
|
74 |
||
4675.3.1
by Abel Deuring
HWDB data upload form added |
75 |
distributionset = getUtility(IDistributionSet) |
4912.1.5
by Christian Reis
Make the hwdb/+fingerprint hierarchy work, add canonical_url to systems and fingerprints, and link them in the web pages' tables. |
76 |
distribution = distributionset.getByName(data['distribution'].lower()) |
4675.3.1
by Abel Deuring
HWDB data upload form added |
77 |
if distribution is not None: |
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
78 |
release = data['distroseries'] |
4675.3.1
by Abel Deuring
HWDB data upload form added |
79 |
architecture = data['architecture'] |
80 |
try: |
|
81 |
distroseries = distribution.getSeries(release) |
|
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
82 |
except NotFoundError: |
83 |
self.addErrorHeader("distroseries", |
|
84 |
"%s isn't a valid distribution series" |
|
85 |
% data['distroseries']) |
|
86 |
return
|
|
87 |
||
88 |
try: |
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
89 |
distroarchseries = distroseries[architecture] |
90 |
except NotFoundError: |
|
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
91 |
self.addErrorHeader("distroarchseries", |
92 |
"%s isn't a valid distribution architecture" |
|
93 |
% data['architecture']) |
|
94 |
return
|
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
95 |
else: |
96 |
distroarchseries = None |
|
97 |
||
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
98 |
fingerprintset = getUtility(IHWSystemFingerprintSet) |
4675.3.1
by Abel Deuring
HWDB data upload form added |
99 |
fingerprint = fingerprintset.getByName(data['system']) |
100 |
if fingerprint is None: |
|
101 |
fingerprint = fingerprintset.createFingerprint(data['system']) |
|
102 |
||
103 |
filesize = len(data['submission_data']) |
|
4675.2.3
by Abel Deuring
implemented reviewr's comments |
104 |
submission_file = self.request.form[ |
105 |
self.widgets['submission_data'].name] |
|
106 |
submission_file.seek(0) |
|
107 |
# convert a filename with "path elements" to a regular filename
|
|
108 |
filename = submission_file.filename.replace('/', '-') |
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
109 |
|
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
110 |
hw_submissionset = getUtility(IHWSubmissionSet) |
4974.3.2
by Abel Deuring
No automatic creation of Person records for HWDB from unknown email addresses |
111 |
hw_submissionset.createSubmission( |
112 |
date_created=data['date_created'], |
|
113 |
format=data['format'], |
|
114 |
private=data['private'], |
|
115 |
contactable=data['contactable'], |
|
116 |
submission_key=data['submission_key'], |
|
117 |
emailaddress=data['emailaddress'], |
|
118 |
distroarchseries=distroarchseries, |
|
119 |
raw_submission=submission_file, |
|
120 |
filename=filename, |
|
121 |
filesize=filesize, |
|
122 |
system_fingerprint=data['system']) |
|
4675.2.3
by Abel Deuring
implemented reviewr's comments |
123 |
|
4912.1.2
by Christian Reis
Change the way headers are used to communicate problems. |
124 |
self.addCustomHeader('OK data stored') |
4675.3.1
by Abel Deuring
HWDB data upload form added |
125 |
self.request.response.addNotification( |
126 |
"Thank you for your submission.") |
|
127 |
||
128 |
def render(self): |
|
4675.2.3
by Abel Deuring
implemented reviewr's comments |
129 |
"""See ILaunchpadFormView."""
|
130 |
if self.errors: |
|
131 |
self.setHeadersForHWDBClient() |
|
132 |
return LaunchpadFormView.render(self) |
|
133 |
||
134 |
def setHeadersForHWDBClient(self): |
|
4675.3.1
by Abel Deuring
HWDB data upload form added |
135 |
"""Add headers that help the HWDB client detect a successful upload.
|
136 |
||
137 |
An upload is normally not made by a regular web browser, but by the
|
|
138 |
HWDB client. In order to allow the client to easily detect a
|
|
139 |
successful as well as an failed request, add some HTTP headers
|
|
140 |
to the response.
|
|
141 |
"""
|
|
4675.2.3
by Abel Deuring
implemented reviewr's comments |
142 |
for field in self.form_fields: |
143 |
field_name = field.__name__ |
|
5243.1.1
by Jonathan Knowles
Renaming method getWidgetError (in LaunchpadFormView) to getFieldError. |
144 |
error = self.getFieldError(field_name) |
4675.2.3
by Abel Deuring
implemented reviewr's comments |
145 |
if error: |
4912.1.2
by Christian Reis
Change the way headers are used to communicate problems. |
146 |
self.addErrorHeader(field_name, error) |
147 |
||
148 |
def addErrorHeader(self, field_name, error): |
|
149 |
"""Adds a header informing an error to automated clients."""
|
|
5311.1.1
by David Murphy
Reformatted HWDB upload error messages to be less ambiguous. |
150 |
return self.addCustomHeader(u"Error in field '%s' - %s" % |
151 |
(field_name, error)) |
|
4912.1.2
by Christian Reis
Change the way headers are used to communicate problems. |
152 |
|
153 |
def addCustomHeader(self, value): |
|
154 |
"""Adds a custom header to HWDB clients."""
|
|
155 |
self.request.response.setHeader( |
|
156 |
u'X-Launchpad-HWDB-Submission', value) |
|
157 |
||
4675.3.1
by Abel Deuring
HWDB data upload form added |
158 |
|
159 |
class HWDBPersonSubmissionsView(LaunchpadView): |
|
160 |
"""View class for preseting HWDB submissions by a person."""
|
|
161 |
||
9521.2.1
by Gary Poster
handle the majority of the remaining launchpad templates for 3.0: remove 6 and change 6. Also remove another template bigjools requested removal for. |
162 |
@property
|
163 |
def label(self): |
|
164 |
return 'Hardware submissions for %s' % (self.context.title,) |
|
165 |
||
166 |
@property
|
|
167 |
def page_title(self): |
|
168 |
return "Hardware Database submissions by %s" % (self.context.title,) |
|
169 |
||
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
170 |
def getAllBatched(self): |
171 |
"""Return the list of HWDB submissions made by this person."""
|
|
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
172 |
hw_submissionset = getUtility(IHWSubmissionSet) |
173 |
submissions = hw_submissionset.getByOwner(self.context, self.user) |
|
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
174 |
return BatchNavigator(submissions, self.request) |
4675.3.1
by Abel Deuring
HWDB data upload form added |
175 |
|
176 |
def userIsOwner(self): |
|
177 |
"""Return true, if self.context == self.user"""
|
|
178 |
return self.context == self.user |
|
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
179 |
|
180 |
||
4912.1.1
by Christian Reis
Merge Abel's work, add a test for textual HWDB output, and make sure submission IDs are valid_names too. |
181 |
class HWDBSubmissionTextView(LaunchpadView): |
182 |
"""Renders a HWDBSubmission in parseable text."""
|
|
183 |
def render(self): |
|
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
184 |
data = {} |
185 |
data["date_created"] = self.context.date_created |
|
186 |
data["date_submitted"] = self.context.date_submitted |
|
187 |
data["format"] = self.context.format.name |
|
188 |
||
189 |
dar = self.context.distroarchseries |
|
190 |
if dar: |
|
191 |
data["distribution"] = dar.distroseries.distribution.name |
|
192 |
data["distribution_series"] = dar.distroseries.version |
|
193 |
data["architecture"] = dar.architecturetag |
|
194 |
else: |
|
195 |
data["distribution"] = "(unknown)" |
|
196 |
data["distribution_series"] = "(unknown)" |
|
197 |
data["architecture"] = "(unknown)" |
|
198 |
||
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
199 |
data["system_fingerprint"] = ( |
200 |
self.context.system_fingerprint.fingerprint) |
|
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
201 |
data["url"] = self.context.raw_submission.http_url |
202 |
||
203 |
return dedent(""" |
|
204 |
Date-Created: %(date_created)s |
|
205 |
Date-Submitted: %(date_submitted)s |
|
206 |
Format: %(format)s |
|
207 |
Distribution: %(distribution)s |
|
208 |
Distribution-Series: %(distribution_series)s |
|
209 |
Architecture: %(architecture)s |
|
210 |
System: %(system_fingerprint)s |
|
211 |
Submission URL: %(url)s""" % data) |
|
4912.1.1
by Christian Reis
Merge Abel's work, add a test for textual HWDB output, and make sure submission IDs are valid_names too. |
212 |
|
213 |
||
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
214 |
class HWDBApplicationNavigation(Navigation): |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
215 |
"""Navigation class for HWDBSubmissionSet."""
|
216 |
||
217 |
usedfor = IHWDBApplication |
|
218 |
||
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
219 |
@stepthrough('+submission') |
220 |
def traverse_submission(self, name): |
|
221 |
user = getUtility(ILaunchBag).user |
|
222 |
submission = getUtility(IHWSubmissionSet).getBySubmissionKey( |
|
223 |
name, user=user) |
|
224 |
return submission |
|
225 |
||
4912.1.5
by Christian Reis
Make the hwdb/+fingerprint hierarchy work, add canonical_url to systems and fingerprints, and link them in the web pages' tables. |
226 |
@stepthrough('+fingerprint') |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
227 |
def traverse_hwdb_fingerprint(self, name): |
228 |
return HWDBFingerprintSetView(self.context, self.request, name) |
|
229 |
||
7353.2.1
by Abel Deuring
Webservice API for IHWDevice |
230 |
@stepthrough('+device') |
231 |
def traverse_device(self, id): |
|
232 |
try: |
|
233 |
id = int(id) |
|
234 |
except ValueError: |
|
235 |
raise NotFoundError('invalid value for ID: %r' % id) |
|
236 |
return getUtility(IHWDeviceSet).getByID(id) |
|
237 |
||
9094.2.2
by Abel Deuring
implemented reviewer's comments |
238 |
@stepthrough('+deviceclass') |
239 |
def traverse_device_class(self, id): |
|
240 |
try: |
|
241 |
id = int(id) |
|
242 |
except ValueError: |
|
243 |
raise NotFoundError('invalid value for ID: %r' % id) |
|
244 |
return getUtility(IHWDeviceClassSet).get(id) |
|
245 |
||
7353.2.6
by Abel Deuring
added missing implementation to access a single HWDriver instance via the webservice API |
246 |
@stepthrough('+driver') |
247 |
def traverse_driver(self, id): |
|
248 |
try: |
|
249 |
id = int(id) |
|
250 |
except ValueError: |
|
251 |
raise NotFoundError('invalid value for ID: %r' % id) |
|
252 |
return getUtility(IHWDriverSet).getByID(id) |
|
253 |
||
7525.3.1
by Abel Deuring
Webservice API for IHWSubmissionDevice |
254 |
@stepthrough('+submissiondevice') |
255 |
def traverse_submissiondevice(self, id): |
|
256 |
try: |
|
257 |
id = int(id) |
|
258 |
except ValueError: |
|
259 |
raise NotFoundError('invalid value for ID: %r' % id) |
|
7525.3.2
by Abel Deuring
implemented reviewer's comments |
260 |
return getUtility(IHWSubmissionDeviceSet).get(id) |
7525.3.1
by Abel Deuring
Webservice API for IHWSubmissionDevice |
261 |
|
7553.1.1
by Abel Deuring
webservice API for IHWVendorID |
262 |
@stepthrough('+hwvendorid') |
263 |
def traverse_hw_vendor_id(self, id): |
|
264 |
try: |
|
265 |
id = int(id) |
|
266 |
except ValueError: |
|
267 |
raise NotFoundError('invalid value for ID: %r' % id) |
|
268 |
return getUtility(IHWVendorIDSet).get(id) |
|
269 |
||
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
270 |
|
271 |
class HWDBFingerprintSetView(LaunchpadView): |
|
272 |
"""View class for lists of HWDB submissions for a system fingerprint."""
|
|
273 |
||
274 |
implements(IBrowserPublisher) |
|
9521.2.1
by Gary Poster
handle the majority of the remaining launchpad templates for 3.0: remove 6 and change 6. Also remove another template bigjools requested removal for. |
275 |
label = page_title = "Hardware Database submissions for a fingerprint" |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
276 |
|
277 |
template = ViewPageTemplateFile( |
|
4675.2.3
by Abel Deuring
implemented reviewr's comments |
278 |
'../templates/hwdb-fingerprint-submissions.pt') |
4912.1.3
by Christian Reis
Implement the plain-text view for HWDB submissions, check that submission IDs are really valid_names, rename submission_id to submission_key consistently, rename distro*release to distro*series consistently. What else.. |
279 |
|
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
280 |
def __init__(self, context, request, system_name): |
281 |
LaunchpadView.__init__(self, context, request) |
|
282 |
self.system_name = system_name |
|
283 |
||
284 |
def getAllBatched(self): |
|
285 |
"""A BatchNavigator instance with the submissions."""
|
|
4675.4.1
by Christian Reis
Fix some broken merges, update test to properly use sampledata, rename HWDBSubmission* to HWSubmission. |
286 |
submissions = getUtility(IHWSubmissionSet).getByFingerprintName( |
4675.3.2
by Abel Deuring
added views for hwdb submissiions from a person and submissions for a fingerprint |
287 |
self.system_name, self.user) |
288 |
return BatchNavigator(submissions, self.request) |
|
289 |
||
290 |
def browserDefault(self, request): |
|
291 |
"""See `IBrowserPublisher`."""
|
|
292 |
return self, () |
|
293 |
||
294 |
def showOwner(self, submission): |
|
295 |
"""Check if the owner can be shown in the list.
|
|
296 |
"""
|
|
297 |
return (submission.owner is not None |
|
298 |
and (submission.contactable |
|
299 |
or (submission.owner == self.user))) |