| OLD | NEW |
| (Empty) |
| 1 # Copyright 2010 Google Inc. | |
| 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 from boto.s3.key import Key as S3Key | |
| 23 | |
| 24 class Key(S3Key): | |
| 25 | |
| 26 def add_email_grant(self, permission, email_address): | |
| 27 """ | |
| 28 Convenience method that provides a quick way to add an email grant to a | |
| 29 key. This method retrieves the current ACL, creates a new grant based on | |
| 30 the parameters passed in, adds that grant to the ACL and then PUT's the | |
| 31 new ACL back to GS. | |
| 32 | |
| 33 :type permission: string | |
| 34 :param permission: The permission being granted. Should be one of: | |
| 35 READ|FULL_CONTROL | |
| 36 See http://code.google.com/apis/storage/docs/developer-guide.html#au
thorization | |
| 37 for more details on permissions. | |
| 38 | |
| 39 :type email_address: string | |
| 40 :param email_address: The email address associated with the Google | |
| 41 account to which you are granting the permission. | |
| 42 """ | |
| 43 acl = self.get_acl() | |
| 44 acl.add_email_grant(permission, email_address) | |
| 45 self.set_acl(acl) | |
| 46 | |
| 47 def add_user_grant(self, permission, user_id): | |
| 48 """ | |
| 49 Convenience method that provides a quick way to add a canonical user | |
| 50 grant to a key. This method retrieves the current ACL, creates a new | |
| 51 grant based on the parameters passed in, adds that grant to the ACL and | |
| 52 then PUT's the new ACL back to GS. | |
| 53 | |
| 54 :type permission: string | |
| 55 :param permission: The permission being granted. Should be one of: | |
| 56 READ|FULL_CONTROL | |
| 57 See http://code.google.com/apis/storage/docs/developer-guide.html#au
thorization | |
| 58 for more details on permissions. | |
| 59 | |
| 60 :type user_id: string | |
| 61 :param user_id: The canonical user id associated with the GS account to | |
| 62 which you are granting the permission. | |
| 63 """ | |
| 64 acl = self.get_acl() | |
| 65 acl.add_user_grant(permission, user_id) | |
| 66 self.set_acl(acl) | |
| 67 | |
| 68 def add_group_email_grant(self, permission, email_address, headers=None): | |
| 69 """ | |
| 70 Convenience method that provides a quick way to add an email group | |
| 71 grant to a key. This method retrieves the current ACL, creates a new | |
| 72 grant based on the parameters passed in, adds that grant to the ACL and | |
| 73 then PUT's the new ACL back to GS. | |
| 74 | |
| 75 :type permission: string | |
| 76 :param permission: The permission being granted. Should be one of: | |
| 77 READ|FULL_CONTROL | |
| 78 See http://code.google.com/apis/storage/docs/developer-guide.html#au
thorization | |
| 79 for more details on permissions. | |
| 80 | |
| 81 :type email_address: string | |
| 82 :param email_address: The email address associated with the Google | |
| 83 Group to which you are granting the permission. | |
| 84 """ | |
| 85 acl = self.get_acl(headers=headers) | |
| 86 acl.add_group_email_grant(permission, email_address) | |
| 87 self.set_acl(acl, headers=headers) | |
| 88 | |
| 89 def add_group_grant(self, permission, group_id): | |
| 90 """ | |
| 91 Convenience method that provides a quick way to add a canonical group | |
| 92 grant to a key. This method retrieves the current ACL, creates a new | |
| 93 grant based on the parameters passed in, adds that grant to the ACL and | |
| 94 then PUT's the new ACL back to GS. | |
| 95 | |
| 96 :type permission: string | |
| 97 :param permission: The permission being granted. Should be one of: | |
| 98 READ|FULL_CONTROL | |
| 99 See http://code.google.com/apis/storage/docs/developer-guide.html#au
thorization | |
| 100 for more details on permissions. | |
| 101 | |
| 102 :type group_id: string | |
| 103 :param group_id: The canonical group id associated with the Google | |
| 104 Groups account you are granting the permission to. | |
| 105 """ | |
| 106 acl = self.get_acl() | |
| 107 acl.add_group_grant(permission, group_id) | |
| 108 self.set_acl(acl) | |
| 109 | |
| 110 def set_contents_from_file(self, fp, headers=None, replace=True, | |
| 111 cb=None, num_cb=10, policy=None, md5=None, | |
| 112 res_upload_handler=None): | |
| 113 """ | |
| 114 Store an object in GS using the name of the Key object as the | |
| 115 key in GS and the contents of the file pointed to by 'fp' as the | |
| 116 contents. | |
| 117 | |
| 118 :type fp: file | |
| 119 :param fp: the file whose contents are to be uploaded | |
| 120 | |
| 121 :type headers: dict | |
| 122 :param headers: additional HTTP headers to be sent with the PUT request. | |
| 123 | |
| 124 :type replace: bool | |
| 125 :param replace: If this parameter is False, the method will first check | |
| 126 to see if an object exists in the bucket with the same key. If it | |
| 127 does, it won't overwrite it. The default value is True which will | |
| 128 overwrite the object. | |
| 129 | |
| 130 :type cb: function | |
| 131 :param cb: a callback function that will be called to report | |
| 132 progress on the upload. The callback should accept two integer | |
| 133 parameters, the first representing the number of bytes that have | |
| 134 been successfully transmitted to GS and the second representing the | |
| 135 total number of bytes that need to be transmitted. | |
| 136 | |
| 137 :type num_cb: int | |
| 138 :param num_cb: (optional) If a callback is specified with the cb | |
| 139 parameter, this parameter determines the granularity of the callback | |
| 140 by defining the maximum number of times the callback will be called | |
| 141 during the file transfer. | |
| 142 | |
| 143 :type policy: :class:`boto.gs.acl.CannedACLStrings` | |
| 144 :param policy: A canned ACL policy that will be applied to the new key | |
| 145 in GS. | |
| 146 | |
| 147 :type md5: A tuple containing the hexdigest version of the MD5 checksum | |
| 148 of the file as the first element and the Base64-encoded version of | |
| 149 the plain checksum as the second element. This is the same format | |
| 150 returned by the compute_md5 method. | |
| 151 :param md5: If you need to compute the MD5 for any reason prior to | |
| 152 upload, it's silly to have to do it twice so this param, if present, | |
| 153 will be used as the MD5 values of the file. Otherwise, the checksum | |
| 154 will be computed. | |
| 155 | |
| 156 :type res_upload_handler: ResumableUploadHandler | |
| 157 :param res_upload_handler: If provided, this handler will perform the | |
| 158 upload. | |
| 159 | |
| 160 TODO: At some point we should refactor the Bucket and Key classes, | |
| 161 to move functionality common to all providers into a parent class, | |
| 162 and provider-specific functionality into subclasses (rather than | |
| 163 just overriding/sharing code the way it currently works). | |
| 164 """ | |
| 165 provider = self.bucket.connection.provider | |
| 166 headers = headers or {} | |
| 167 if policy: | |
| 168 headers[provider.acl_header] = policy | |
| 169 if hasattr(fp, 'name'): | |
| 170 self.path = fp.name | |
| 171 if self.bucket != None: | |
| 172 if not md5: | |
| 173 md5 = self.compute_md5(fp) | |
| 174 else: | |
| 175 # Even if md5 is provided, still need to set size of content. | |
| 176 fp.seek(0, 2) | |
| 177 self.size = fp.tell() | |
| 178 fp.seek(0) | |
| 179 self.md5 = md5[0] | |
| 180 self.base64md5 = md5[1] | |
| 181 if self.name == None: | |
| 182 self.name = self.md5 | |
| 183 if not replace: | |
| 184 k = self.bucket.lookup(self.name) | |
| 185 if k: | |
| 186 return | |
| 187 if res_upload_handler: | |
| 188 res_upload_handler.send_file(self, fp, headers, cb, num_cb) | |
| 189 else: | |
| 190 # Not a resumable transfer so use basic send_file mechanism. | |
| 191 self.send_file(fp, headers, cb, num_cb) | |
| 192 | |
| 193 def set_contents_from_filename(self, filename, headers=None, replace=True, | |
| 194 cb=None, num_cb=10, policy=None, md5=None, | |
| 195 reduced_redundancy=None, | |
| 196 res_upload_handler=None): | |
| 197 """ | |
| 198 Store an object in GS using the name of the Key object as the | |
| 199 key in GS and the contents of the file named by 'filename'. | |
| 200 See set_contents_from_file method for details about the | |
| 201 parameters. | |
| 202 | |
| 203 :type filename: string | |
| 204 :param filename: The name of the file that you want to put onto GS | |
| 205 | |
| 206 :type headers: dict | |
| 207 :param headers: Additional headers to pass along with the request to GS. | |
| 208 | |
| 209 :type replace: bool | |
| 210 :param replace: If True, replaces the contents of the file if it | |
| 211 already exists. | |
| 212 | |
| 213 :type cb: function | |
| 214 :param cb: (optional) a callback function that will be called to report | |
| 215 progress on the download. The callback should accept two integer | |
| 216 parameters, the first representing the number of bytes that have | |
| 217 been successfully transmitted from GS and the second representing | |
| 218 the total number of bytes that need to be transmitted. | |
| 219 | |
| 220 :type cb: int | |
| 221 :param num_cb: (optional) If a callback is specified with the cb | |
| 222 parameter this parameter determines the granularity of the callback | |
| 223 by defining the maximum number of times the callback will be called | |
| 224 during the file transfer. | |
| 225 | |
| 226 :type policy: :class:`boto.gs.acl.CannedACLStrings` | |
| 227 :param policy: A canned ACL policy that will be applied to the new key | |
| 228 in GS. | |
| 229 | |
| 230 :type md5: A tuple containing the hexdigest version of the MD5 checksum | |
| 231 of the file as the first element and the Base64-encoded version of | |
| 232 the plain checksum as the second element. This is the same format | |
| 233 returned by the compute_md5 method. | |
| 234 :param md5: If you need to compute the MD5 for any reason prior to | |
| 235 upload, it's silly to have to do it twice so this param, if present, | |
| 236 will be used as the MD5 values of the file. Otherwise, the checksum | |
| 237 will be computed. | |
| 238 | |
| 239 :type res_upload_handler: ResumableUploadHandler | |
| 240 :param res_upload_handler: If provided, this handler will perform the | |
| 241 upload. | |
| 242 """ | |
| 243 fp = open(filename, 'rb') | |
| 244 self.set_contents_from_file(fp, headers, replace, cb, num_cb, | |
| 245 policy, md5, res_upload_handler) | |
| 246 fp.close() | |
| OLD | NEW |