Merge branch 'master' of github.com:spulec/moto
Conflicts: moto/s3/models.py moto/s3/responses.py
This commit is contained in:
commit
f25caa872d
113 changed files with 4360 additions and 1446 deletions
|
|
@ -1,23 +1,54 @@
|
|||
# from boto.s3.bucket import Bucket
|
||||
# from boto.s3.key import Key
|
||||
import os
|
||||
import base64
|
||||
import md5
|
||||
import datetime
|
||||
import hashlib
|
||||
|
||||
from moto.core import BaseBackend
|
||||
from moto.core.utils import iso_8601_datetime, rfc_1123_datetime
|
||||
from .utils import clean_key_name
|
||||
|
||||
|
||||
class FakeKey(object):
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.last_modified = datetime.datetime.now()
|
||||
self._metadata = {}
|
||||
|
||||
def set_metadata(self, key, metadata):
|
||||
self._metadata[key] = metadata
|
||||
|
||||
def append_to_value(self, value):
|
||||
self.value += value
|
||||
self.last_modified = datetime.datetime.now()
|
||||
|
||||
@property
|
||||
def etag(self):
|
||||
value_md5 = md5.new()
|
||||
value_md5 = hashlib.md5()
|
||||
value_md5.update(self.value)
|
||||
return '"{0}"'.format(value_md5.hexdigest())
|
||||
|
||||
@property
|
||||
def last_modified_ISO8601(self):
|
||||
return iso_8601_datetime(self.last_modified)
|
||||
|
||||
@property
|
||||
def last_modified_RFC1123(self):
|
||||
# Different datetime formats depending on how the key is obtained
|
||||
# https://github.com/boto/boto/issues/466
|
||||
return rfc_1123_datetime(self.last_modified)
|
||||
|
||||
@property
|
||||
def metadata(self):
|
||||
return self._metadata
|
||||
|
||||
@property
|
||||
def response_dict(self):
|
||||
return {
|
||||
'etag': self.etag,
|
||||
'last-modified': self.last_modified_RFC1123,
|
||||
}
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
return len(self.value)
|
||||
|
|
@ -87,13 +118,23 @@ class S3Backend(BaseBackend):
|
|||
return None
|
||||
|
||||
def set_key(self, bucket_name, key_name, value):
|
||||
key_name = clean_key_name(key_name)
|
||||
|
||||
bucket = self.buckets[bucket_name]
|
||||
new_key = FakeKey(name=key_name, value=value)
|
||||
bucket.keys[key_name] = new_key
|
||||
|
||||
return new_key
|
||||
|
||||
def append_to_key(self, bucket_name, key_name, value):
|
||||
key_name = clean_key_name(key_name)
|
||||
|
||||
key = self.get_key(bucket_name, key_name)
|
||||
key.append_to_value(value)
|
||||
return key
|
||||
|
||||
def get_key(self, bucket_name, key_name):
|
||||
key_name = clean_key_name(key_name)
|
||||
bucket = self.get_bucket(bucket_name)
|
||||
if bucket:
|
||||
return bucket.keys.get(key_name)
|
||||
|
|
@ -120,21 +161,24 @@ class S3Backend(BaseBackend):
|
|||
multipart = bucket.multiparts[multipart_id]
|
||||
return multipart.set_part(part_id, value)
|
||||
|
||||
def prefix_query(self, bucket, prefix):
|
||||
def prefix_query(self, bucket, prefix, delimiter):
|
||||
key_results = set()
|
||||
folder_results = set()
|
||||
if prefix:
|
||||
for key_name, key in bucket.keys.iteritems():
|
||||
if key_name.startswith(prefix):
|
||||
if '/' in key_name.lstrip(prefix):
|
||||
key_without_prefix = key_name.lstrip(prefix).split("/")[0]
|
||||
folder_results.add("{}{}".format(prefix, key_without_prefix))
|
||||
key_without_prefix = key_name.replace(prefix, "", 1)
|
||||
if delimiter and delimiter in key_without_prefix:
|
||||
# If delimiter, we need to split out folder_results
|
||||
key_without_delimiter = key_without_prefix.split(delimiter)[0]
|
||||
folder_results.add("{}{}{}".format(prefix, key_without_delimiter, delimiter))
|
||||
else:
|
||||
key_results.add(key)
|
||||
else:
|
||||
for key_name, key in bucket.keys.iteritems():
|
||||
if '/' in key_name:
|
||||
folder_results.add(key_name.split("/")[0])
|
||||
if delimiter and delimiter in key_name:
|
||||
# If delimiter, we need to split out folder_results
|
||||
folder_results.add(key_name.split(delimiter)[0])
|
||||
else:
|
||||
key_results.add(key)
|
||||
|
||||
|
|
@ -144,10 +188,13 @@ class S3Backend(BaseBackend):
|
|||
return key_results, folder_results
|
||||
|
||||
def delete_key(self, bucket_name, key_name):
|
||||
key_name = clean_key_name(key_name)
|
||||
bucket = self.buckets[bucket_name]
|
||||
return bucket.keys.pop(key_name)
|
||||
|
||||
def copy_key(self, src_bucket_name, src_key_name, dest_bucket_name, dest_key_name):
|
||||
src_key_name = clean_key_name(src_key_name)
|
||||
dest_key_name = clean_key_name(dest_key_name)
|
||||
src_bucket = self.buckets[src_bucket_name]
|
||||
dest_bucket = self.buckets[dest_bucket_name]
|
||||
dest_bucket.keys[dest_key_name] = src_bucket.keys[src_key_name]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue