Skip to content

Commit e0badf8

Browse files
committed
Add black code linter
1 parent 78e50f8 commit e0badf8

21 files changed

+318
-300
lines changed

.fussyfox.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
- bandit
2+
- black
23
- flake8
34
- pydocstyle
45
- isort

s3file/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
default_app_config = 's3file.apps.S3FileConfig'
1+
default_app_config = "s3file.apps.S3FileConfig"

s3file/apps.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66

77
class S3FileConfig(AppConfig):
8-
name = 's3file'
9-
verbose_name = 'S3File'
8+
name = "s3file"
9+
verbose_name = "S3File"
1010

1111
def ready(self):
1212
from django import forms
@@ -15,14 +15,18 @@ def ready(self):
1515

1616
from .forms import S3FileInputMixin
1717

18-
if isinstance(default_storage, (S3Boto3Storage, FileSystemStorage)) and \
19-
S3FileInputMixin not in forms.ClearableFileInput.__bases__:
20-
forms.ClearableFileInput.__bases__ = \
21-
(S3FileInputMixin,) + forms.ClearableFileInput.__bases__
18+
if (
19+
isinstance(default_storage, (S3Boto3Storage, FileSystemStorage))
20+
and S3FileInputMixin not in forms.ClearableFileInput.__bases__
21+
):
22+
forms.ClearableFileInput.__bases__ = (
23+
S3FileInputMixin,
24+
) + forms.ClearableFileInput.__bases__
2225

2326
elif S3FileInputMixin in forms.ClearableFileInput.__bases__:
2427
forms.ClearableFileInput.__bases__ = tuple(
25-
cls for cls in forms.ClearableFileInput.__bases__
28+
cls
29+
for cls in forms.ClearableFileInput.__bases__
2630
if cls is not S3FileInputMixin
2731
)
2832

s3file/checks.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ def storage_check(app_configs, **kwargs):
66
if isinstance(default_storage, FileSystemStorage):
77
return [
88
Error(
9-
'FileSystemStorage should not be used in a production environment.',
10-
hint='Please verify your DEFAULT_FILE_STORAGE setting.',
11-
id='s3file.E001',
9+
"FileSystemStorage should not be used in a production environment.",
10+
hint="Please verify your DEFAULT_FILE_STORAGE setting.",
11+
id="s3file.E001",
1212
)
1313
]
1414
return []

s3file/forms.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99

1010
from s3file.storages import storage
1111

12-
logger = logging.getLogger('s3file')
12+
logger = logging.getLogger("s3file")
1313

1414

1515
class S3FileInputMixin:
1616
"""FileInput that uses JavaScript to directly upload to Amazon S3."""
1717

1818
needs_multipart_form = False
19-
upload_path = str(getattr(
20-
settings, 'S3FILE_UPLOAD_PATH', pathlib.PurePosixPath('tmp', 's3file')
21-
))
19+
upload_path = str(
20+
getattr(settings, "S3FILE_UPLOAD_PATH", pathlib.PurePosixPath("tmp", "s3file"))
21+
)
2222
upload_path = safe_join(str(storage.location), upload_path)
2323
expires = settings.SESSION_COOKIE_AGE
2424

@@ -33,25 +33,24 @@ def client(self):
3333
def build_attrs(self, *args, **kwargs):
3434
attrs = super().build_attrs(*args, **kwargs)
3535

36-
accept = attrs.get('accept')
36+
accept = attrs.get("accept")
3737
response = self.client.generate_presigned_post(
3838
self.bucket_name,
39-
str(pathlib.PurePosixPath(self.upload_folder, '${filename}')),
39+
str(pathlib.PurePosixPath(self.upload_folder, "${filename}")),
4040
Conditions=self.get_conditions(accept),
4141
ExpiresIn=self.expires,
4242
)
4343

4444
defaults = {
45-
'data-fields-%s' % key: value
46-
for key, value in response['fields'].items()
45+
"data-fields-%s" % key: value for key, value in response["fields"].items()
4746
}
48-
defaults['data-url'] = response['url']
47+
defaults["data-url"] = response["url"]
4948
defaults.update(attrs)
5049

5150
try:
52-
defaults['class'] += ' s3file'
51+
defaults["class"] += " s3file"
5352
except KeyError:
54-
defaults['class'] = 's3file'
53+
defaults["class"] = "s3file"
5554
return defaults
5655

5756
def get_conditions(self, accept):
@@ -60,9 +59,9 @@ def get_conditions(self, accept):
6059
["starts-with", "$key", str(self.upload_folder)],
6160
{"success_action_status": "201"},
6261
]
63-
if accept and ',' not in accept:
64-
top_type, sub_type = accept.split('/', 1)
65-
if sub_type == '*':
62+
if accept and "," not in accept:
63+
top_type, sub_type = accept.split("/", 1)
64+
if sub_type == "*":
6665
conditions.append(["starts-with", "$Content-Type", "%s/" % top_type])
6766
else:
6867
conditions.append({"Content-Type": accept})
@@ -73,14 +72,14 @@ def get_conditions(self, accept):
7372

7473
@cached_property
7574
def upload_folder(self):
76-
return str(pathlib.PurePosixPath(
77-
self.upload_path,
78-
base64.urlsafe_b64encode(
79-
uuid.uuid4().bytes
80-
).decode('utf-8').rstrip('=\n'),
81-
)) # S3 uses POSIX paths
75+
return str(
76+
pathlib.PurePosixPath(
77+
self.upload_path,
78+
base64.urlsafe_b64encode(uuid.uuid4().bytes)
79+
.decode("utf-8")
80+
.rstrip("=\n"),
81+
)
82+
) # S3 uses POSIX paths
8283

8384
class Media:
84-
js = (
85-
's3file/js/s3file.js' if settings.DEBUG else 's3file/js/s3file.min.js',
86-
)
85+
js = ("s3file/js/s3file.js" if settings.DEBUG else "s3file/js/s3file.min.js",)

s3file/middleware.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,20 @@
66

77
from . import views
88

9-
logger = logging.getLogger('s3file')
9+
logger = logging.getLogger("s3file")
1010

1111

1212
class S3FileMiddleware:
13-
1413
def __init__(self, get_response):
1514
self.get_response = get_response
1615

1716
def __call__(self, request):
18-
file_fields = json.loads(request.POST.get('s3file', '[]'))
17+
file_fields = json.loads(request.POST.get("s3file", "[]"))
1918
for field_name in file_fields:
20-
paths = json.loads(request.POST.get(field_name, '[]'))
19+
paths = json.loads(request.POST.get(field_name, "[]"))
2120
request.FILES.setlist(field_name, list(self.get_files_from_storage(paths)))
2221

23-
if local_dev and request.path == '/__s3_mock__/':
22+
if local_dev and request.path == "/__s3_mock__/":
2423
return views.S3MockView.as_view()(request)
2524

2625
return self.get_response(request)
@@ -30,7 +29,7 @@ def get_files_from_storage(paths):
3029
"""Return S3 file where the name does not include the path."""
3130
for path in paths:
3231
if storage.location:
33-
path = path.replace(os.path.dirname(storage.location) + '/', '', 1)
32+
path = path.replace(os.path.dirname(storage.location) + "/", "", 1)
3433
try:
3534
f = storage.open(path)
3635
f.name = os.path.basename(path)

s3file/storages.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
class S3MockStorage(FileSystemStorage):
1313
@property
1414
def location(self):
15-
return getattr(settings, 'AWS_LOCATION', '')
15+
return getattr(settings, "AWS_LOCATION", "")
1616

1717
def path(self, name):
1818
return safe_join(os.path.abspath(self.base_location), self.location, name)
@@ -24,34 +24,32 @@ class client:
2424
def generate_presigned_post(bucket_name, key, **policy):
2525
policy = json.dumps(policy).encode()
2626
policy_b64 = base64.b64encode(policy).decode()
27-
date = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
27+
date = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
2828
aws_id = getattr(
29-
settings, 'AWS_ACCESS_KEY_ID',
30-
'AWS_ACCESS_KEY_ID',
29+
settings,
30+
"AWS_ACCESS_KEY_ID",
31+
"AWS_ACCESS_KEY_ID",
3132
)
3233
fields = {
33-
'x-amz-algorithm': 'AWS4-HMAC-SHA256',
34-
'x-amz-date': date,
35-
'x-amz-credential': aws_id,
36-
'policy': policy_b64,
37-
'key': key,
34+
"x-amz-algorithm": "AWS4-HMAC-SHA256",
35+
"x-amz-date": date,
36+
"x-amz-credential": aws_id,
37+
"policy": policy_b64,
38+
"key": key,
3839
}
3940
signature = hmac.new(
4041
settings.SECRET_KEY.encode(),
4142
policy + date.encode(),
42-
'sha256',
43+
"sha256",
4344
).digest()
4445
signature = base64.b64encode(signature).decode()
4546
return {
46-
'url': '/__s3_mock__/',
47-
'fields': {
48-
'x-amz-signature': signature,
49-
**fields
50-
},
47+
"url": "/__s3_mock__/",
48+
"fields": {"x-amz-signature": signature, **fields},
5149
}
5250

5351
class bucket:
54-
name = 'test-bucket'
52+
name = "test-bucket"
5553

5654

5755
local_dev = isinstance(default_storage, FileSystemStorage)

s3file/views.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,48 @@
88
from django.core.files.storage import default_storage
99
from django.views import generic
1010

11-
logger = logging.getLogger('s3file')
11+
logger = logging.getLogger("s3file")
1212

1313

1414
class S3MockView(generic.View):
15-
1615
def post(self, request):
17-
success_action_status = request.POST.get('success_action_status', 201)
16+
success_action_status = request.POST.get("success_action_status", 201)
1817
try:
19-
file = request.FILES['file']
20-
key = request.POST['key']
21-
date = request.POST['x-amz-date']
22-
signature = request.POST['x-amz-signature']
23-
policy = request.POST['policy']
18+
file = request.FILES["file"]
19+
key = request.POST["key"]
20+
date = request.POST["x-amz-date"]
21+
signature = request.POST["x-amz-signature"]
22+
policy = request.POST["policy"]
2423
except KeyError:
25-
logger.exception('bad request')
24+
logger.exception("bad request")
2625
return http.HttpResponseBadRequest()
2726

2827
try:
2928
signature = base64.b64decode(signature.encode())
3029
policy = base64.b64decode(policy.encode())
3130

3231
calc_sign = hmac.new(
33-
settings.SECRET_KEY.encode(),
34-
policy + date.encode(),
35-
'sha256'
32+
settings.SECRET_KEY.encode(), policy + date.encode(), "sha256"
3633
).digest()
3734
except ValueError:
38-
logger.exception('bad request')
35+
logger.exception("bad request")
3936
return http.HttpResponseBadRequest()
4037

4138
if not hmac.compare_digest(signature, calc_sign):
42-
logger.warning('bad signature')
39+
logger.warning("bad signature")
4340
return http.HttpResponseForbidden()
4441

45-
key = key.replace('${filename}', file.name)
42+
key = key.replace("${filename}", file.name)
4643
etag = hashlib.md5(file.read()).hexdigest() # nosec
4744
file.seek(0)
4845
key = default_storage.save(key, file)
4946
return http.HttpResponse(
50-
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
47+
'<?xml version="1.0" encoding="UTF-8"?>'
5148
"<PostResponse>"
5249
f"<Location>{settings.MEDIA_URL}{key}</Location>"
5350
f"<Bucket>{getattr(settings, 'AWS_STORAGE_BUCKET_NAME')}</Bucket>"
5451
f"<Key>{key}</Key>"
55-
f"<ETag>\"{etag}\"</ETag>"
52+
f'<ETag>"{etag}"</ETag>'
5653
"</PostResponse>",
5754
status=success_action_status,
5855
)

setup.cfg

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,10 @@ test = pytest
6464
addopts = --cov=s3file --cov-report xml --tb=short -rxs
6565
DJANGO_SETTINGS_MODULE=tests.testapp.settings
6666

67-
[tox:tox]
68-
envlist = py{36,37}-dj{111,22,master}
69-
70-
[testenv]
71-
deps=
72-
dj111: https://github.com/django/django/archive/stable/1.11.x.tar.gz#egg=django
73-
dj22: https://github.com/django/django/archive/stable/2.2.x.tar.gz#egg=django
74-
djmaster: https://github.com/django/django/archive/master.tar.gz#egg=django
75-
commands=
76-
python setup.py test
77-
7867
[flake8]
7968
max-line-length=88
80-
exclude = venv,.tox,.eggs
69+
select = C,E,F,W,B,B950
70+
ignore = E203, E501, W503, E731
8171

8272
[pydocstyle]
8373
add_ignore = D1

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/usr/bin/env python
22
from setuptools import setup
33

4-
setup(name='django-s3file', use_scm_version=True)
4+
setup(name="django-s3file", use_scm_version=True)

tests/conftest.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from selenium.common.exceptions import WebDriverException
99

1010

11-
@pytest.yield_fixture(scope='session')
11+
@pytest.yield_fixture(scope="session")
1212
def driver():
1313
chrome_options = webdriver.ChromeOptions()
1414
chrome_options.headless = True
@@ -24,26 +24,26 @@ def driver():
2424
@pytest.fixture
2525
def upload_file(request):
2626
path = tempfile.mkdtemp()
27-
file_name = os.path.join(path, '%s.txt' % request.node.name)
28-
with open(file_name, 'w') as f:
27+
file_name = os.path.join(path, "%s.txt" % request.node.name)
28+
with open(file_name, "w") as f:
2929
f.write(request.node.name)
3030
return file_name
3131

3232

3333
@pytest.fixture
3434
def another_upload_file(request):
3535
path = tempfile.mkdtemp()
36-
file_name = os.path.join(path, 'another_%s.txt' % request.node.name)
37-
with open(file_name, 'w') as f:
36+
file_name = os.path.join(path, "another_%s.txt" % request.node.name)
37+
with open(file_name, "w") as f:
3838
f.write(request.node.name)
3939
return file_name
4040

4141

4242
@pytest.fixture
4343
def yet_another_upload_file(request):
4444
path = tempfile.mkdtemp()
45-
file_name = os.path.join(path, 'yet_another_%s.txt' % request.node.name)
46-
with open(file_name, 'w') as f:
45+
file_name = os.path.join(path, "yet_another_%s.txt" % request.node.name)
46+
with open(file_name, "w") as f:
4747
f.write(request.node.name)
4848
return file_name
4949

@@ -53,5 +53,5 @@ def filemodel(request, db):
5353
from tests.testapp.models import FileModel
5454

5555
return FileModel.objects.create(
56-
file=ContentFile(request.node.name, '%s.txt' % request.node.name)
56+
file=ContentFile(request.node.name, "%s.txt" % request.node.name)
5757
)

tests/test_apps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
class TestS3FileConfig:
1010
def test_ready(self, settings):
11-
app = S3FileConfig('s3file', importlib.import_module('tests.testapp'))
11+
app = S3FileConfig("s3file", importlib.import_module("tests.testapp"))
1212
app.ready()
1313
assert not isinstance(forms.ClearableFileInput(), S3FileInputMixin)
14-
settings.DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
14+
settings.DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
1515
app.ready()
1616
assert isinstance(forms.ClearableFileInput(), S3FileInputMixin)

0 commit comments

Comments
 (0)