-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paths3.py
99 lines (78 loc) · 2.47 KB
/
s3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
try:
import unzip_requirements
except ImportError:
pass
import hashlib
import logging
import boto3
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
BUCKET = 'word-art-svgs'
def get_checksum(str):
"""
Generates a sha1 checksum for a given string
:param str:
:return: str
"""
hash_object = hashlib.sha1(b'%s' % str)
hex_dig = hash_object.hexdigest()
return hex_dig
def get_filename(checksum):
"""
Appends .svg to a checksum
:param checksum:
:return: str
"""
return '%s.svg' % checksum
def is_duplicate_checksum(checksum):
"""
Check if this file has been created before - if so, just return the S3 URL.
Returns None otherwise
:param checksum: str
:return: str|None
"""
s3 = boto3.client('s3')
response = s3.list_objects_v2(
Bucket=BUCKET,
EncodingType='url',
Prefix=checksum
)
if response['KeyCount'] > 0 and len(response['Contents']) > 0:
return 'https://s3.amazonaws.com/%s/%s' % (BUCKET, response['Contents'][0]['Key'])
return None
def upload_svg(filename, xml_string):
"""
Uploads the SVG file to S3, and returns the URL of the object
:param filename: str
:param xml_string: str
:return: str
"""
s3 = boto3.client('s3')
response = s3.put_object(
ACL='public-read',
Body=xml_string,
Bucket=BUCKET,
Key=filename,
StorageClass='REDUCED_REDUNDANCY',
)
return 'https://s3.amazonaws.com/%s/%s' % (BUCKET, filename)
def save_svg(xml_string, checksum=None):
"""
Saves an XML string as a unique (checksummed) file in S3
And returns the URL of the file
Checks for duplicates along the way using sha1 to find collisions
:param xml_string:
:param checksum: str|None
:return: str
"""
if checksum is None:
checksum = get_checksum(xml_string) # Get checksum of this file
existing_url = is_duplicate_checksum(checksum) # Make sure it's unique
if existing_url is not None: # We've generated this file before.
logger.info('Duplicate detected for %s' % checksum)
return existing_url # If dupe_check has a value, it's a URL to an existing (duplicate) file.
# Usually, we've already checked for a duplicate - the above logic is just for cases
# where we need to generate the checksum on the backend
filename = get_filename(checksum)
url = upload_svg(filename, xml_string)
return url