Index: third_party/boto/boto/file/key.py |
diff --git a/third_party/boto/boto/file/key.py b/third_party/boto/boto/file/key.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..2f20cae5b9e958dba9ffa1791224a134b1ec5ded |
--- /dev/null |
+++ b/third_party/boto/boto/file/key.py |
@@ -0,0 +1,199 @@ |
+# Copyright 2010 Google Inc. |
+# Copyright (c) 2011, Nexenta Systems Inc. |
+# |
+# Permission is hereby granted, free of charge, to any person obtaining a |
+# copy of this software and associated documentation files (the |
+# "Software"), to deal in the Software without restriction, including |
+# without limitation the rights to use, copy, modify, merge, publish, dis- |
+# tribute, sublicense, and/or sell copies of the Software, and to permit |
+# persons to whom the Software is furnished to do so, subject to the fol- |
+# lowing conditions: |
+# |
+# The above copyright notice and this permission notice shall be included |
+# in all copies or substantial portions of the Software. |
+# |
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
+# IN THE SOFTWARE. |
+ |
+# File representation of key, for use with "file://" URIs. |
+ |
+import os, shutil, StringIO |
+import sys |
+ |
+class Key(object): |
+ |
+ KEY_STREAM_READABLE = 0x01 |
+ KEY_STREAM_WRITABLE = 0x02 |
+ KEY_STREAM = (KEY_STREAM_READABLE | KEY_STREAM_WRITABLE) |
+ KEY_REGULAR_FILE = 0x00 |
+ |
+ def __init__(self, bucket, name, fp=None, key_type=KEY_REGULAR_FILE): |
+ self.bucket = bucket |
+ self.full_path = name |
+ if name == '-': |
+ self.name = None |
+ self.size = None |
+ else: |
+ self.name = name |
+ self.size = os.stat(name).st_size |
+ self.key_type = key_type |
+ if key_type == self.KEY_STREAM_READABLE: |
+ self.fp = sys.stdin |
+ self.full_path = '<STDIN>' |
+ elif key_type == self.KEY_STREAM_WRITABLE: |
+ self.fp = sys.stdout |
+ self.full_path = '<STDOUT>' |
+ else: |
+ self.fp = fp |
+ |
+ def __str__(self): |
+ return 'file://' + self.full_path |
+ |
+ def get_file(self, fp, headers=None, cb=None, num_cb=10, torrent=False): |
+ """ |
+ Retrieves a file from a Key |
+ |
+ :type fp: file |
+ :param fp: File pointer to put the data into |
+ |
+ :type headers: string |
+ :param: ignored in this subclass. |
+ |
+ :type cb: function |
+ :param cb: ignored in this subclass. |
+ |
+ :type cb: int |
+ :param num_cb: ignored in this subclass. |
+ """ |
+ if self.key_type & self.KEY_STREAM_WRITABLE: |
+ raise BotoClientError('Stream is not readable') |
+ elif self.key_type & self.KEY_STREAM_READABLE: |
+ key_file = self.fp |
+ else: |
+ key_file = open(self.full_path, 'rb') |
+ try: |
+ shutil.copyfileobj(key_file, fp) |
+ finally: |
+ key_file.close() |
+ |
+ def set_contents_from_file(self, fp, headers=None, replace=True, cb=None, |
+ num_cb=10, policy=None, md5=None): |
+ """ |
+ Store an object in a file using the name of the Key object as the |
+ key in file URI and the contents of the file pointed to by 'fp' as the |
+ contents. |
+ |
+ :type fp: file |
+ :param fp: the file whose contents to upload |
+ |
+ :type headers: dict |
+ :param headers: ignored in this subclass. |
+ |
+ :type replace: bool |
+ :param replace: If this parameter is False, the method |
+ will first check to see if an object exists in the |
+ bucket with the same key. If it does, it won't |
+ overwrite it. The default value is True which will |
+ overwrite the object. |
+ |
+ :type cb: function |
+ :param cb: ignored in this subclass. |
+ |
+ :type cb: int |
+ :param num_cb: ignored in this subclass. |
+ |
+ :type policy: :class:`boto.s3.acl.CannedACLStrings` |
+ :param policy: ignored in this subclass. |
+ |
+ :type md5: A tuple containing the hexdigest version of the MD5 checksum |
+ of the file as the first element and the Base64-encoded |
+ version of the plain checksum as the second element. |
+ This is the same format returned by the compute_md5 method. |
+ :param md5: ignored in this subclass. |
+ """ |
+ if self.key_type & self.KEY_STREAM_READABLE: |
+ raise BotoClientError('Stream is not writable') |
+ elif self.key_type & self.KEY_STREAM_WRITABLE: |
+ key_file = self.fp |
+ else: |
+ if not replace and os.path.exists(self.full_path): |
+ return |
+ key_file = open(self.full_path, 'wb') |
+ try: |
+ shutil.copyfileobj(fp, key_file) |
+ finally: |
+ key_file.close() |
+ |
+ def get_contents_to_file(self, fp, headers=None, cb=None, num_cb=None, |
+ torrent=False, version_id=None, |
+ res_download_handler=None, response_headers=None): |
+ """ |
+ Copy contents from the current file to the file pointed to by 'fp'. |
+ |
+ :type fp: File-like object |
+ :param fp: |
+ |
+ :type headers: dict |
+ :param headers: Unused in this subclass. |
+ |
+ :type cb: function |
+ :param cb: Unused in this subclass. |
+ |
+ :type cb: int |
+ :param num_cb: Unused in this subclass. |
+ |
+ :type torrent: bool |
+ :param torrent: Unused in this subclass. |
+ |
+ :type res_upload_handler: ResumableDownloadHandler |
+ :param res_download_handler: Unused in this subclass. |
+ |
+ :type response_headers: dict |
+ :param response_headers: Unused in this subclass. |
+ """ |
+ shutil.copyfileobj(self.fp, fp) |
+ |
+ def get_contents_as_string(self, headers=None, cb=None, num_cb=10, |
+ torrent=False): |
+ """ |
+ Retrieve file data from the Key, and return contents as a string. |
+ |
+ :type headers: dict |
+ :param headers: ignored in this subclass. |
+ |
+ :type cb: function |
+ :param cb: ignored in this subclass. |
+ |
+ :type cb: int |
+ :param num_cb: ignored in this subclass. |
+ |
+ :type cb: int |
+ :param num_cb: ignored in this subclass. |
+ |
+ :type torrent: bool |
+ :param torrent: ignored in this subclass. |
+ |
+ :rtype: string |
+ :returns: The contents of the file as a string |
+ """ |
+ |
+ fp = StringIO.StringIO() |
+ self.get_contents_to_file(fp) |
+ return fp.getvalue() |
+ |
+ def is_stream(self): |
+ return (self.key_type & self.KEY_STREAM) |
+ |
+ def close(self): |
+ """ |
+ Closes fp associated with underlying file. |
+ Caller should call this method when done with this class, to avoid |
+ using up OS resources (e.g., when iterating over a large number |
+ of files). |
+ """ |
+ self.fp.close() |