Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: third_party/gsutil/boto/mturk/question.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21
22
23 class Question(object):
24 template = "<Question>%(items)s</Question>"
25
26 def __init__(self, identifier, content, answer_spec,
27 is_required=False, display_name=None):
28 # copy all of the parameters into object attributes
29 self.__dict__.update(vars())
30 del self.self
31
32 def get_as_params(self, label='Question'):
33 return {label: self.get_as_xml()}
34
35 def get_as_xml(self):
36 items = [
37 SimpleField('QuestionIdentifier', self.identifier),
38 SimpleField('IsRequired', str(self.is_required).lower()),
39 self.content,
40 self.answer_spec,
41 ]
42 if self.display_name is not None:
43 items.insert(1, SimpleField('DisplayName', self.display_name))
44 items = ''.join(item.get_as_xml() for item in items)
45 return self.template % vars()
46
47 try:
48 from lxml import etree
49
50 class ValidatingXML(object):
51
52 def validate(self):
53 import urllib2
54 schema_src_file = urllib2.urlopen(self.schema_url)
55 schema_doc = etree.parse(schema_src_file)
56 schema = etree.XMLSchema(schema_doc)
57 doc = etree.fromstring(self.get_as_xml())
58 schema.assertValid(doc)
59 except ImportError:
60 class ValidatingXML(object):
61
62 def validate(self):
63 pass
64
65
66 class ExternalQuestion(ValidatingXML):
67 """
68 An object for constructing an External Question.
69 """
70 schema_url = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchem as/2006-07-14/ExternalQuestion.xsd"
71 template = '<ExternalQuestion xmlns="%(schema_url)s"><ExternalURL>%%(externa l_url)s</ExternalURL><FrameHeight>%%(frame_height)s</FrameHeight></ExternalQuest ion>' % vars()
72
73 def __init__(self, external_url, frame_height):
74 self.external_url = external_url
75 self.frame_height = frame_height
76
77 def get_as_params(self, label='ExternalQuestion'):
78 return {label: self.get_as_xml()}
79
80 def get_as_xml(self):
81 return self.template % vars(self)
82
83
84 class XMLTemplate:
85 def get_as_xml(self):
86 return self.template % vars(self)
87
88
89 class SimpleField(object, XMLTemplate):
90 """
91 A Simple name/value pair that can be easily rendered as XML.
92
93 >>> SimpleField('Text', 'A text string').get_as_xml()
94 '<Text>A text string</Text>'
95 """
96 template = '<%(field)s>%(value)s</%(field)s>'
97
98 def __init__(self, field, value):
99 self.field = field
100 self.value = value
101
102
103 class Binary(object, XMLTemplate):
104 template = """<Binary><MimeType><Type>%(type)s</Type><SubType>%(subtype)s</S ubType></MimeType><DataURL>%(url)s</DataURL><AltText>%(alt_text)s</AltText></Bin ary>"""
105
106 def __init__(self, type, subtype, url, alt_text):
107 self.__dict__.update(vars())
108 del self.self
109
110
111 class List(list):
112 """A bulleted list suitable for OrderedContent or Overview content"""
113 def get_as_xml(self):
114 items = ''.join('<ListItem>%s</ListItem>' % item for item in self)
115 return '<List>%s</List>' % items
116
117
118 class Application(object):
119 template = "<Application><%(class_)s>%(content)s</%(class_)s></Application>"
120 parameter_template = "<Name>%(name)s</Name><Value>%(value)s</Value>"
121
122 def __init__(self, width, height, **parameters):
123 self.width = width
124 self.height = height
125 self.parameters = parameters
126
127 def get_inner_content(self, content):
128 content.append_field('Width', self.width)
129 content.append_field('Height', self.height)
130 for name, value in self.parameters.items():
131 value = self.parameter_template % vars()
132 content.append_field('ApplicationParameter', value)
133
134 def get_as_xml(self):
135 content = OrderedContent()
136 self.get_inner_content(content)
137 content = content.get_as_xml()
138 class_ = self.__class__.__name__
139 return self.template % vars()
140
141
142 class HTMLQuestion(ValidatingXML):
143 schema_url = 'http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchem as/2011-11-11/HTMLQuestion.xsd'
144 template = '<HTMLQuestion xmlns=\"%(schema_url)s\"><HTMLContent><![CDATA[<!D OCTYPE html>%%(html_form)s]]></HTMLContent><FrameHeight>%%(frame_height)s</Frame Height></HTMLQuestion>' % vars()
145
146 def __init__(self, html_form, frame_height):
147 self.html_form = html_form
148 self.frame_height = frame_height
149
150 def get_as_params(self, label="HTMLQuestion"):
151 return {label: self.get_as_xml()}
152
153 def get_as_xml(self):
154 return self.template % vars(self)
155
156
157 class JavaApplet(Application):
158 def __init__(self, path, filename, *args, **kwargs):
159 self.path = path
160 self.filename = filename
161 super(JavaApplet, self).__init__(*args, **kwargs)
162
163 def get_inner_content(self, content):
164 content = OrderedContent()
165 content.append_field('AppletPath', self.path)
166 content.append_field('AppletFilename', self.filename)
167 super(JavaApplet, self).get_inner_content(content)
168
169
170 class Flash(Application):
171 def __init__(self, url, *args, **kwargs):
172 self.url = url
173 super(Flash, self).__init__(*args, **kwargs)
174
175 def get_inner_content(self, content):
176 content = OrderedContent()
177 content.append_field('FlashMovieURL', self.url)
178 super(Flash, self).get_inner_content(content)
179
180
181 class FormattedContent(object, XMLTemplate):
182 schema_url = 'http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchem as/2006-07-14/FormattedContentXHTMLSubset.xsd'
183 template = '<FormattedContent><![CDATA[%(content)s]]></FormattedContent>'
184
185 def __init__(self, content):
186 self.content = content
187
188
189 class OrderedContent(list):
190
191 def append_field(self, field, value):
192 self.append(SimpleField(field, value))
193
194 def get_as_xml(self):
195 return ''.join(item.get_as_xml() for item in self)
196
197
198 class Overview(OrderedContent):
199 template = '<Overview>%(content)s</Overview>'
200
201 def get_as_params(self, label='Overview'):
202 return {label: self.get_as_xml()}
203
204 def get_as_xml(self):
205 content = super(Overview, self).get_as_xml()
206 return self.template % vars()
207
208
209 class QuestionForm(ValidatingXML, list):
210 """
211 From the AMT API docs:
212
213 The top-most element of the QuestionForm data structure is a
214 QuestionForm element. This element contains optional Overview
215 elements and one or more Question elements. There can be any
216 number of these two element types listed in any order. The
217 following example structure has an Overview element and a
218 Question element followed by a second Overview element and
219 Question element--all within the same QuestionForm.
220
221 ::
222
223 <QuestionForm xmlns="[the QuestionForm schema URL]">
224 <Overview>
225 [...]
226 </Overview>
227 <Question>
228 [...]
229 </Question>
230 <Overview>
231 [...]
232 </Overview>
233 <Question>
234 [...]
235 </Question>
236 [...]
237 </QuestionForm>
238
239 QuestionForm is implemented as a list, so to construct a
240 QuestionForm, simply append Questions and Overviews (with at least
241 one Question).
242 """
243 schema_url = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchem as/2005-10-01/QuestionForm.xsd"
244 xml_template = """<QuestionForm xmlns="%(schema_url)s">%%(items)s</QuestionF orm>""" % vars()
245
246 def is_valid(self):
247 return (
248 any(isinstance(item, Question) for item in self)
249 and
250 all(isinstance(item, (Question, Overview)) for item in self)
251 )
252
253 def get_as_xml(self):
254 assert self.is_valid(), "QuestionForm contains invalid elements"
255 items = ''.join(item.get_as_xml() for item in self)
256 return self.xml_template % vars()
257
258
259 class QuestionContent(OrderedContent):
260 template = '<QuestionContent>%(content)s</QuestionContent>'
261
262 def get_as_xml(self):
263 content = super(QuestionContent, self).get_as_xml()
264 return self.template % vars()
265
266
267 class AnswerSpecification(object):
268 template = '<AnswerSpecification>%(spec)s</AnswerSpecification>'
269
270 def __init__(self, spec):
271 self.spec = spec
272
273 def get_as_xml(self):
274 spec = self.spec.get_as_xml()
275 return self.template % vars()
276
277
278 class Constraints(OrderedContent):
279 template = '<Constraints>%(content)s</Constraints>'
280
281 def get_as_xml(self):
282 content = super(Constraints, self).get_as_xml()
283 return self.template % vars()
284
285
286 class Constraint(object):
287 def get_attributes(self):
288 pairs = zip(self.attribute_names, self.attribute_values)
289 attrs = ' '.join(
290 '%s="%d"' % (name, value)
291 for (name, value) in pairs
292 if value is not None
293 )
294 return attrs
295
296 def get_as_xml(self):
297 attrs = self.get_attributes()
298 return self.template % vars()
299
300
301 class NumericConstraint(Constraint):
302 attribute_names = 'minValue', 'maxValue'
303 template = '<IsNumeric %(attrs)s />'
304
305 def __init__(self, min_value=None, max_value=None):
306 self.attribute_values = min_value, max_value
307
308
309 class LengthConstraint(Constraint):
310 attribute_names = 'minLength', 'maxLength'
311 template = '<Length %(attrs)s />'
312
313 def __init__(self, min_length=None, max_length=None):
314 self.attribute_values = min_length, max_length
315
316
317 class RegExConstraint(Constraint):
318 attribute_names = 'regex', 'errorText', 'flags'
319 template = '<AnswerFormatRegex %(attrs)s />'
320
321 def __init__(self, pattern, error_text=None, flags=None):
322 self.attribute_values = pattern, error_text, flags
323
324 def get_attributes(self):
325 pairs = zip(self.attribute_names, self.attribute_values)
326 attrs = ' '.join(
327 '%s="%s"' % (name, value)
328 for (name, value) in pairs
329 if value is not None
330 )
331 return attrs
332
333
334 class NumberOfLinesSuggestion(object):
335 template = '<NumberOfLinesSuggestion>%(num_lines)s</NumberOfLinesSuggestion> '
336
337 def __init__(self, num_lines=1):
338 self.num_lines = num_lines
339
340 def get_as_xml(self):
341 num_lines = self.num_lines
342 return self.template % vars()
343
344
345 class FreeTextAnswer(object):
346 template = '<FreeTextAnswer>%(items)s</FreeTextAnswer>'
347
348 def __init__(self, default=None, constraints=None, num_lines=None):
349 self.default = default
350 if constraints is None:
351 self.constraints = Constraints()
352 else:
353 self.constraints = Constraints(constraints)
354 self.num_lines = num_lines
355
356 def get_as_xml(self):
357 items = [self.constraints]
358 if self.default:
359 items.append(SimpleField('DefaultText', self.default))
360 if self.num_lines:
361 items.append(NumberOfLinesSuggestion(self.num_lines))
362 items = ''.join(item.get_as_xml() for item in items)
363 return self.template % vars()
364
365
366 class FileUploadAnswer(object):
367 template = """<FileUploadAnswer><MaxFileSizeInBytes>%(max_bytes)d</MaxFileSi zeInBytes><MinFileSizeInBytes>%(min_bytes)d</MinFileSizeInBytes></FileUploadAnsw er>"""
368
369 def __init__(self, min_bytes, max_bytes):
370 assert 0 <= min_bytes <= max_bytes <= 2 * 10 ** 9
371 self.min_bytes = min_bytes
372 self.max_bytes = max_bytes
373
374 def get_as_xml(self):
375 return self.template % vars(self)
376
377
378 class SelectionAnswer(object):
379 """
380 A class to generate SelectionAnswer XML data structures.
381 Does not yet implement Binary selection options.
382 """
383 SELECTIONANSWER_XML_TEMPLATE = """<SelectionAnswer>%s%s<Selections>%s</Selec tions></SelectionAnswer>""" # % (count_xml, style_xml, selections_xml)
384 SELECTION_XML_TEMPLATE = """<Selection><SelectionIdentifier>%s</SelectionIde ntifier>%s</Selection>""" # (identifier, value_xml)
385 SELECTION_VALUE_XML_TEMPLATE = """<%s>%s</%s>""" # (type, value, type)
386 STYLE_XML_TEMPLATE = """<StyleSuggestion>%s</StyleSuggestion>""" # (style)
387 MIN_SELECTION_COUNT_XML_TEMPLATE = """<MinSelectionCount>%s</MinSelectionCou nt>""" # count
388 MAX_SELECTION_COUNT_XML_TEMPLATE = """<MaxSelectionCount>%s</MaxSelectionCou nt>""" # count
389 ACCEPTED_STYLES = ['radiobutton', 'dropdown', 'checkbox', 'list', 'combobox' , 'multichooser']
390 OTHER_SELECTION_ELEMENT_NAME = 'OtherSelection'
391
392 def __init__(self, min=1, max=1, style=None, selections=None, type='text', o ther=False):
393
394 if style is not None:
395 if style in SelectionAnswer.ACCEPTED_STYLES:
396 self.style_suggestion = style
397 else:
398 raise ValueError("style '%s' not recognized; should be one of %s " % (style, ', '.join(SelectionAnswer.ACCEPTED_STYLES)))
399 else:
400 self.style_suggestion = None
401
402 if selections is None:
403 raise ValueError("SelectionAnswer.__init__(): selections must be a n on-empty list of (content, identifier) tuples")
404 else:
405 self.selections = selections
406
407 self.min_selections = min
408 self.max_selections = max
409
410 assert len(selections) >= self.min_selections, "# of selections is less than minimum of %d" % self.min_selections
411 #assert len(selections) <= self.max_selections, "# of selections exceeds maximum of %d" % self.max_selections
412
413 self.type = type
414
415 self.other = other
416
417 def get_as_xml(self):
418 if self.type == 'text':
419 TYPE_TAG = "Text"
420 elif self.type == 'binary':
421 TYPE_TAG = "Binary"
422 else:
423 raise ValueError("illegal type: %s; must be either 'text' or 'binary '" % str(self.type))
424
425 # build list of <Selection> elements
426 selections_xml = ""
427 for tpl in self.selections:
428 value_xml = SelectionAnswer.SELECTION_VALUE_XML_TEMPLATE % (TYPE_TAG , tpl[0], TYPE_TAG)
429 selection_xml = SelectionAnswer.SELECTION_XML_TEMPLATE % (tpl[1], va lue_xml)
430 selections_xml += selection_xml
431
432 if self.other:
433 # add OtherSelection element as xml if available
434 if hasattr(self.other, 'get_as_xml'):
435 assert isinstance(self.other, FreeTextAnswer), 'OtherSelection c an only be a FreeTextAnswer'
436 selections_xml += self.other.get_as_xml().replace('FreeTextAnswe r', 'OtherSelection')
437 else:
438 selections_xml += "<OtherSelection />"
439
440 if self.style_suggestion is not None:
441 style_xml = SelectionAnswer.STYLE_XML_TEMPLATE % self.style_suggesti on
442 else:
443 style_xml = ""
444
445 if self.style_suggestion != 'radiobutton':
446 count_xml = SelectionAnswer.MIN_SELECTION_COUNT_XML_TEMPLATE %self.m in_selections
447 count_xml += SelectionAnswer.MAX_SELECTION_COUNT_XML_TEMPLATE %self. max_selections
448 else:
449 count_xml = ""
450
451 ret = SelectionAnswer.SELECTIONANSWER_XML_TEMPLATE % (count_xml, style_x ml, selections_xml)
452
453 # return XML
454 return ret
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698