You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
6.4 KiB

4 years ago
  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. from boto.s3.user import User
  22. class ResultSet(list):
  23. """
  24. The ResultSet is used to pass results back from the Amazon services
  25. to the client. It is light wrapper around Python's :py:class:`list` class,
  26. with some additional methods for parsing XML results from AWS.
  27. Because I don't really want any dependencies on external libraries,
  28. I'm using the standard SAX parser that comes with Python. The good news is
  29. that it's quite fast and efficient but it makes some things rather
  30. difficult.
  31. You can pass in, as the marker_elem parameter, a list of tuples.
  32. Each tuple contains a string as the first element which represents
  33. the XML element that the resultset needs to be on the lookout for
  34. and a Python class as the second element of the tuple. Each time the
  35. specified element is found in the XML, a new instance of the class
  36. will be created and popped onto the stack.
  37. :ivar str next_token: A hash used to assist in paging through very long
  38. result sets. In most cases, passing this value to certain methods
  39. will give you another 'page' of results.
  40. """
  41. def __init__(self, marker_elem=None):
  42. list.__init__(self)
  43. if isinstance(marker_elem, list):
  44. self.markers = marker_elem
  45. else:
  46. self.markers = []
  47. self.marker = None
  48. self.key_marker = None
  49. self.next_marker = None # avail when delimiter used
  50. self.next_key_marker = None
  51. self.next_upload_id_marker = None
  52. self.next_version_id_marker = None
  53. self.next_generation_marker = None
  54. self.version_id_marker = None
  55. self.is_truncated = False
  56. self.next_token = None
  57. self.status = True
  58. def startElement(self, name, attrs, connection):
  59. for t in self.markers:
  60. if name == t[0]:
  61. obj = t[1](connection)
  62. self.append(obj)
  63. return obj
  64. if name == 'Owner':
  65. # Makes owner available for get_service and
  66. # perhaps other lists where not handled by
  67. # another element.
  68. self.owner = User()
  69. return self.owner
  70. return None
  71. def to_boolean(self, value, true_value='true'):
  72. if value == true_value:
  73. return True
  74. else:
  75. return False
  76. def endElement(self, name, value, connection):
  77. if name == 'IsTruncated':
  78. self.is_truncated = self.to_boolean(value)
  79. elif name == 'Marker':
  80. self.marker = value
  81. elif name == 'KeyMarker':
  82. self.key_marker = value
  83. elif name == 'NextMarker':
  84. self.next_marker = value
  85. elif name == 'NextKeyMarker':
  86. self.next_key_marker = value
  87. elif name == 'VersionIdMarker':
  88. self.version_id_marker = value
  89. elif name == 'NextVersionIdMarker':
  90. self.next_version_id_marker = value
  91. elif name == 'NextGenerationMarker':
  92. self.next_generation_marker = value
  93. elif name == 'UploadIdMarker':
  94. self.upload_id_marker = value
  95. elif name == 'NextUploadIdMarker':
  96. self.next_upload_id_marker = value
  97. elif name == 'Bucket':
  98. self.bucket = value
  99. elif name == 'MaxUploads':
  100. self.max_uploads = int(value)
  101. elif name == 'MaxItems':
  102. self.max_items = int(value)
  103. elif name == 'Prefix':
  104. self.prefix = value
  105. elif name == 'return':
  106. self.status = self.to_boolean(value)
  107. elif name == 'StatusCode':
  108. self.status = self.to_boolean(value, 'Success')
  109. elif name == 'ItemName':
  110. self.append(value)
  111. elif name == 'NextToken':
  112. self.next_token = value
  113. elif name == 'nextToken':
  114. self.next_token = value
  115. # Code exists which expects nextToken to be available, so we
  116. # set it here to remain backwards-compatibile.
  117. self.nextToken = value
  118. elif name == 'BoxUsage':
  119. try:
  120. connection.box_usage += float(value)
  121. except:
  122. pass
  123. elif name == 'IsValid':
  124. self.status = self.to_boolean(value, 'True')
  125. else:
  126. setattr(self, name, value)
  127. class BooleanResult(object):
  128. def __init__(self, marker_elem=None):
  129. self.status = True
  130. self.request_id = None
  131. self.box_usage = None
  132. def __repr__(self):
  133. if self.status:
  134. return 'True'
  135. else:
  136. return 'False'
  137. def __nonzero__(self):
  138. return self.status
  139. def startElement(self, name, attrs, connection):
  140. return None
  141. def to_boolean(self, value, true_value='true'):
  142. if value == true_value:
  143. return True
  144. else:
  145. return False
  146. def endElement(self, name, value, connection):
  147. if name == 'return':
  148. self.status = self.to_boolean(value)
  149. elif name == 'StatusCode':
  150. self.status = self.to_boolean(value, 'Success')
  151. elif name == 'IsValid':
  152. self.status = self.to_boolean(value, 'True')
  153. elif name == 'RequestId':
  154. self.request_id = value
  155. elif name == 'requestId':
  156. self.request_id = value
  157. elif name == 'BoxUsage':
  158. self.request_id = value
  159. else:
  160. setattr(self, name, value)