Support Python 3 using six
This commit is contained in:
parent
d653a3a3f7
commit
eedb4c4b73
67 changed files with 455 additions and 255 deletions
|
|
@ -5,6 +5,8 @@ import datetime
|
|||
import hashlib
|
||||
import copy
|
||||
import itertools
|
||||
import codecs
|
||||
import six
|
||||
|
||||
from moto.core import BaseBackend
|
||||
from moto.core.utils import iso_8601_datetime, rfc_1123_datetime
|
||||
|
|
@ -59,7 +61,11 @@ class FakeKey(object):
|
|||
def etag(self):
|
||||
if self._etag is None:
|
||||
value_md5 = hashlib.md5()
|
||||
value_md5.update(bytes(self.value))
|
||||
if isinstance(self.value, six.text_type):
|
||||
value = self.value.encode("utf-8")
|
||||
else:
|
||||
value = self.value
|
||||
value_md5.update(value)
|
||||
self._etag = value_md5.hexdigest()
|
||||
return '"{0}"'.format(self._etag)
|
||||
|
||||
|
|
@ -112,9 +118,11 @@ class FakeMultipart(object):
|
|||
def __init__(self, key_name):
|
||||
self.key_name = key_name
|
||||
self.parts = {}
|
||||
self.id = base64.b64encode(os.urandom(UPLOAD_ID_BYTES)).replace('=', '').replace('+', '')
|
||||
rand_b64 = base64.b64encode(os.urandom(UPLOAD_ID_BYTES))
|
||||
self.id = rand_b64.decode('utf-8').replace('=', '').replace('+', '')
|
||||
|
||||
def complete(self):
|
||||
decode_hex = codecs.getdecoder("hex_codec")
|
||||
total = bytearray()
|
||||
md5s = bytearray()
|
||||
last_part_name = len(self.list_parts())
|
||||
|
|
@ -122,7 +130,8 @@ class FakeMultipart(object):
|
|||
for part in self.list_parts():
|
||||
if part.name != last_part_name and len(part.value) < UPLOAD_PART_MIN_SIZE:
|
||||
return None, None
|
||||
md5s.extend(part.etag.replace('"', '').decode('hex'))
|
||||
part_etag = part.etag.replace('"', '')
|
||||
md5s.extend(decode_hex(part_etag)[0])
|
||||
total.extend(part.value)
|
||||
|
||||
etag = hashlib.md5()
|
||||
|
|
@ -296,7 +305,7 @@ class S3Backend(BaseBackend):
|
|||
key_results = set()
|
||||
folder_results = set()
|
||||
if prefix:
|
||||
for key_name, key in bucket.keys.iteritems():
|
||||
for key_name, key in bucket.keys.items():
|
||||
if key_name.startswith(prefix):
|
||||
key_without_prefix = key_name.replace(prefix, "", 1)
|
||||
if delimiter and delimiter in key_without_prefix:
|
||||
|
|
@ -306,7 +315,7 @@ class S3Backend(BaseBackend):
|
|||
else:
|
||||
key_results.add(key)
|
||||
else:
|
||||
for key_name, key in bucket.keys.iteritems():
|
||||
for key_name, key in bucket.keys.items():
|
||||
if delimiter and delimiter in key_name:
|
||||
# If delimiter, we need to split out folder_results
|
||||
folder_results.add(key_name.split(delimiter)[0])
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
from urlparse import parse_qs, urlparse
|
||||
import six
|
||||
from six.moves.urllib.parse import parse_qs, urlparse
|
||||
import re
|
||||
|
||||
from jinja2 import Template
|
||||
|
|
@ -32,7 +33,7 @@ class ResponseObject(object):
|
|||
except MissingBucket:
|
||||
return 404, headers, ""
|
||||
|
||||
if isinstance(response, basestring):
|
||||
if isinstance(response, six.string_types):
|
||||
return 200, headers, response
|
||||
else:
|
||||
status_code, headers, response_content = response
|
||||
|
|
@ -74,7 +75,7 @@ class ResponseObject(object):
|
|||
for unsup in ('delimiter', 'prefix', 'max-uploads'):
|
||||
if unsup in querystring:
|
||||
raise NotImplementedError("Listing multipart uploads with {} has not been implemented yet.".format(unsup))
|
||||
multiparts = list(self.backend.get_all_multiparts(bucket_name).itervalues())
|
||||
multiparts = list(self.backend.get_all_multiparts(bucket_name).values())
|
||||
template = Template(S3_ALL_MULTIPARTS)
|
||||
return 200, headers, template.render(
|
||||
bucket_name=bucket_name,
|
||||
|
|
@ -129,7 +130,7 @@ class ResponseObject(object):
|
|||
|
||||
def _bucket_response_put(self, request, bucket_name, querystring, headers):
|
||||
if 'versioning' in querystring:
|
||||
ver = re.search('<Status>([A-Za-z]+)</Status>', request.body)
|
||||
ver = re.search('<Status>([A-Za-z]+)</Status>', request.body.decode('utf-8'))
|
||||
if ver:
|
||||
self.backend.set_bucket_versioning(bucket_name, ver.group(1))
|
||||
template = Template(S3_BUCKET_VERSIONING)
|
||||
|
|
@ -172,7 +173,7 @@ class ResponseObject(object):
|
|||
else:
|
||||
#HTTPretty, build new form object
|
||||
form = {}
|
||||
for kv in request.body.split('&'):
|
||||
for kv in request.body.decode('utf-8').split('&'):
|
||||
k, v = kv.split('=')
|
||||
form[k] = v
|
||||
|
||||
|
|
@ -198,7 +199,7 @@ class ResponseObject(object):
|
|||
def _bucket_response_delete_keys(self, request, bucket_name, headers):
|
||||
template = Template(S3_DELETE_KEYS_RESPONSE)
|
||||
|
||||
keys = minidom.parseString(request.body).getElementsByTagName('Key')
|
||||
keys = minidom.parseString(request.body.decode('utf-8')).getElementsByTagName('Key')
|
||||
deleted_names = []
|
||||
error_names = []
|
||||
|
||||
|
|
@ -218,7 +219,7 @@ class ResponseObject(object):
|
|||
except MissingBucket:
|
||||
return 404, headers, ""
|
||||
|
||||
if isinstance(response, basestring):
|
||||
if isinstance(response, six.string_types):
|
||||
return 200, headers, response
|
||||
else:
|
||||
status_code, headers, response_content = response
|
||||
|
|
@ -229,7 +230,7 @@ class ResponseObject(object):
|
|||
if replace is True:
|
||||
key.clear_metadata()
|
||||
for header in request.headers:
|
||||
if isinstance(header, basestring):
|
||||
if isinstance(header, six.string_types):
|
||||
result = meta_regex.match(header)
|
||||
if result:
|
||||
meta_key = result.group(0).lower()
|
||||
|
|
@ -359,7 +360,7 @@ class ResponseObject(object):
|
|||
return 204, headers, template.render(bucket=removed_key)
|
||||
|
||||
def _key_response_post(self, body, parsed_url, bucket_name, query, key_name, headers):
|
||||
if body == '' and parsed_url.query == 'uploads':
|
||||
if body == b'' and parsed_url.query == 'uploads':
|
||||
multipart = self.backend.initiate_multipart(bucket_name, key_name)
|
||||
template = Template(S3_MULTIPART_INITIATE_RESPONSE)
|
||||
response = template.render(
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
from __future__ import unicode_literals
|
||||
import re
|
||||
import sys
|
||||
import urllib2
|
||||
import urlparse
|
||||
from six.moves.urllib.parse import urlparse, unquote
|
||||
|
||||
bucket_name_regex = re.compile("(.+).s3.amazonaws.com")
|
||||
|
||||
|
||||
def bucket_name_from_url(url):
|
||||
domain = urlparse.urlparse(url).netloc
|
||||
domain = urlparse(url).netloc
|
||||
|
||||
if domain.startswith('www.'):
|
||||
domain = domain[4:]
|
||||
|
|
@ -26,7 +25,7 @@ def bucket_name_from_url(url):
|
|||
|
||||
|
||||
def clean_key_name(key_name):
|
||||
return urllib2.unquote(key_name)
|
||||
return unquote(key_name)
|
||||
|
||||
|
||||
class _VersionedKeyStore(dict):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue