diff --git a/flask_s3.py b/flask_s3.py index 4dd7d53..67dc89f 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -1,24 +1,51 @@ -import os -import logging import hashlib import json +import logging +import os import re from collections import defaultdict -import re import boto3 import boto3.exceptions from botocore.exceptions import ClientError -from flask import url_for as flask_url_for from flask import current_app +from flask import url_for as flask_url_for logger = logging.getLogger('flask_s3') - import six +# Mapping for Header names to S3 parameters +header_mapping = { + 'cache-control': 'CacheControl', + 'content-disposition': 'ContentDisposition', + 'content-encoding': 'ContentEncoding', + 'content-language': 'ContentLanguage', + 'content-length': 'ContentLength', + 'content-md5': 'ContentMD5', + 'content-type': 'ContentType', + 'expires': 'Expires', +} + + +def split_metadata_params(headers): + """ + Given a dict of headers for s3, seperates those that are boto3 + parameters and those that must be metadata + """ + + params = {} + metadata = {} + for header_name in headers: + if header_name.lower() in header_mapping: + params[header_mapping[header_name.lower()]] = headers[header_name] + else: + metadata[header_name] = headers[header_name] + return metadata, params + + def merge_two_dicts(x, y): - '''Given two dicts, merge them into a new dict as a shallow copy.''' + """Given two dicts, merge them into a new dict as a shallow copy.""" z = x.copy() z.update(y) return z @@ -153,7 +180,7 @@ def _write_files(s3, app, static_url_loc, static_folder, files, bucket, for file_path in files: asset_loc = _path_to_relative_url(file_path) full_key_name = _static_folder_path(static_url_loc, static_folder_rel, - asset_loc) + asset_loc) key_name = full_key_name.lstrip("/") msg = "Uploading %s to %s as %s" % (file_path, bucket, key_name) logger.debug(msg) @@ -180,14 +207,13 @@ def _write_files(s3, app, static_url_loc, static_folder, files, bucket, h[header] = value with open(file_path) as fp: + metadata, params = split_metadata_params(merge_two_dicts(app.config['S3_HEADERS'], h)) s3.put_object(Bucket=bucket, Key=key_name, Body=fp.read(), ACL="public-read", - Metadata=merge_two_dicts(app.config['S3_HEADERS'], h)) - - - + Metadata=metadata, + **params) return new_hashes diff --git a/setup.py b/setup.py index b1d1245..d4ede4e 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ from setuptools import setup setup( name='Flask-S3', - version='0.2.1', + version='0.2.2', url='http://github.com/e-dard/flask-s3', license='WTFPL', author='Edward Robinson', diff --git a/test_flask_static.py b/test_flask_static.py index 05e86c8..d101eca 100644 --- a/test_flask_static.py +++ b/test_flask_static.py @@ -1,8 +1,8 @@ -import unittest import ntpath -import tempfile import os import sys +import tempfile +import unittest try: from unittest.mock import Mock, patch, call, mock_open @@ -10,7 +10,6 @@ except ImportError: from mock import Mock, patch, call, mock_open from flask import Flask, render_template_string, Blueprint import six - import flask_s3 from flask_s3 import FlaskS3 @@ -195,8 +194,8 @@ class S3Tests(unittest.TestCase): expected = {('/home/bar', six.u('/a/bar')): ['/home/bar/b'], ('/home/zoo', six.u('/b/bar')): ['/home/zoo/c', - '/home/zoo/foo/d', - '/home/zoo/foo/e']} + '/home/zoo/foo/d', + '/home/zoo/foo/e']} actual = flask_s3._gather_files(self.app, False) self.assertEqual(expected, actual) @@ -293,11 +292,12 @@ class S3Tests(unittest.TestCase): # We expect each file to be uploaded expected.append(call.put_object(ACL='public-read', - Metadata={'Expires': 'Thu, 31 Dec 2037 23:59:59 GMT', - 'Content-Encoding': 'gzip'}, Bucket=None, Key=filename.lstrip("/"), - Body=data)) + Body=data, + Metadata={}, + Expires='Thu, 31 Dec 2037 23:59:59 GMT', + ContentEncoding='gzip')) files = {(static_url_loc, static_folder): filenames} @@ -317,11 +317,12 @@ class S3Tests(unittest.TestCase): # We expect only this file to be uploaded expected.append(call.put_object(ACL='public-read', - Metadata={'Expires': 'Thu, 31 Dec 2037 23:59:59 GMT', - 'Content-Encoding': 'gzip'}, Bucket=None, Key=filenames[1].lstrip("/"), - Body=data)) + Body=data, + Metadata={}, + Expires='Thu, 31 Dec 2037 23:59:59 GMT', + ContentEncoding='gzip')) new_hashes = flask_s3._upload_files(key_mock, self.app, files, None, hashes=dict(hashes))