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 22from boto.compat import urllib, six 23 24def bucket_lister(bucket, prefix='', delimiter='', marker='', headers=None, 25 encoding_type=None): 26 """ 27 A generator function for listing keys in a bucket. 28 """ 29 more_results = True 30 k = None 31 while more_results: 32 rs = bucket.get_all_keys(prefix=prefix, marker=marker, 33 delimiter=delimiter, headers=headers, 34 encoding_type=encoding_type) 35 for k in rs: 36 yield k 37 if k: 38 marker = rs.next_marker or k.name 39 if marker and encoding_type == "url": 40 if isinstance(marker, six.text_type): 41 marker = marker.encode('utf-8') 42 marker = urllib.parse.unquote(marker) 43 more_results= rs.is_truncated 44 45class BucketListResultSet(object): 46 """ 47 A resultset for listing keys within a bucket. Uses the bucket_lister 48 generator function and implements the iterator interface. This 49 transparently handles the results paging from S3 so even if you have 50 many thousands of keys within the bucket you can iterate over all 51 keys in a reasonably efficient manner. 52 """ 53 54 def __init__(self, bucket=None, prefix='', delimiter='', marker='', 55 headers=None, encoding_type=None): 56 self.bucket = bucket 57 self.prefix = prefix 58 self.delimiter = delimiter 59 self.marker = marker 60 self.headers = headers 61 self.encoding_type = encoding_type 62 63 def __iter__(self): 64 return bucket_lister(self.bucket, prefix=self.prefix, 65 delimiter=self.delimiter, marker=self.marker, 66 headers=self.headers, 67 encoding_type=self.encoding_type) 68 69def versioned_bucket_lister(bucket, prefix='', delimiter='', 70 key_marker='', version_id_marker='', headers=None, 71 encoding_type=None): 72 """ 73 A generator function for listing versions in a bucket. 74 """ 75 more_results = True 76 k = None 77 while more_results: 78 rs = bucket.get_all_versions(prefix=prefix, key_marker=key_marker, 79 version_id_marker=version_id_marker, 80 delimiter=delimiter, headers=headers, 81 max_keys=999, encoding_type=encoding_type) 82 for k in rs: 83 yield k 84 key_marker = rs.next_key_marker 85 version_id_marker = rs.next_version_id_marker 86 more_results= rs.is_truncated 87 88class VersionedBucketListResultSet(object): 89 """ 90 A resultset for listing versions within a bucket. Uses the bucket_lister 91 generator function and implements the iterator interface. This 92 transparently handles the results paging from S3 so even if you have 93 many thousands of keys within the bucket you can iterate over all 94 keys in a reasonably efficient manner. 95 """ 96 97 def __init__(self, bucket=None, prefix='', delimiter='', key_marker='', 98 version_id_marker='', headers=None, encoding_type=None): 99 self.bucket = bucket 100 self.prefix = prefix 101 self.delimiter = delimiter 102 self.key_marker = key_marker 103 self.version_id_marker = version_id_marker 104 self.headers = headers 105 self.encoding_type = encoding_type 106 107 def __iter__(self): 108 return versioned_bucket_lister(self.bucket, prefix=self.prefix, 109 delimiter=self.delimiter, 110 key_marker=self.key_marker, 111 version_id_marker=self.version_id_marker, 112 headers=self.headers, 113 encoding_type=self.encoding_type) 114 115def multipart_upload_lister(bucket, key_marker='', 116 upload_id_marker='', 117 headers=None, encoding_type=None): 118 """ 119 A generator function for listing multipart uploads in a bucket. 120 """ 121 more_results = True 122 k = None 123 while more_results: 124 rs = bucket.get_all_multipart_uploads(key_marker=key_marker, 125 upload_id_marker=upload_id_marker, 126 headers=headers, 127 encoding_type=encoding_type) 128 for k in rs: 129 yield k 130 key_marker = rs.next_key_marker 131 upload_id_marker = rs.next_upload_id_marker 132 more_results= rs.is_truncated 133 134class MultiPartUploadListResultSet(object): 135 """ 136 A resultset for listing multipart uploads within a bucket. 137 Uses the multipart_upload_lister generator function and 138 implements the iterator interface. This 139 transparently handles the results paging from S3 so even if you have 140 many thousands of uploads within the bucket you can iterate over all 141 keys in a reasonably efficient manner. 142 """ 143 def __init__(self, bucket=None, key_marker='', 144 upload_id_marker='', headers=None, encoding_type=None): 145 self.bucket = bucket 146 self.key_marker = key_marker 147 self.upload_id_marker = upload_id_marker 148 self.headers = headers 149 self.encoding_type = encoding_type 150 151 def __iter__(self): 152 return multipart_upload_lister(self.bucket, 153 key_marker=self.key_marker, 154 upload_id_marker=self.upload_id_marker, 155 headers=self.headers, 156 encoding_type=self.encoding_type) 157