Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
102 lines (86 sloc) 3.28 KB
import re
import os
import requests
import tempfile
from django.core.files import File
class FilepickerFile(File):
filepicker_url_regex = re.compile(
r'https?:\/\/www.filepicker.io\/api\/file\/.*')
def __init__(self, url):
if not self.filepicker_url_regex.match(url):
raise ValueError('Not a filepicker.io URL: %s' % url)
self.url = url
def get_file(self, additional_params=None):
'''
Downloads the file from filepicker.io and returns a
Django File wrapper object.
additional_params should include key/values such as:
{
'data-fp-signature': HEXDIGEST,
'data-fp-policy': HEXDIGEST,
}
(in other words, parameters should look like additional_params
of the models)
'''
# clean up any old downloads that are still hanging around
self.cleanup()
# Fetch any fields possibly required for fetching files for reading.
query_params = {}
if additional_params:
for field in ('policy','signature'):
longfield = 'data-fp-{0}'.format(field)
if longfield in additional_params:
query_params[field] = additional_params[longfield]
# iterate through one or more file urls
result = list()
for url in self.url.split(","):
# Append the fields as GET query parameters to the URL in data.
r = requests.get(url, params=query_params, stream=True)
header = r.headers
name = ''
disposition = header.get('Content-Disposition')
if disposition:
name = disposition.rpartition("filename=")[2].strip('" ')
filename = header.get('X-File-Name')
if filename:
name = filename
# Create a temporary file to save to it later
tmp = tempfile.NamedTemporaryFile(mode='w+b')
for chunk in r.iter_content(chunk_size=1024):
if chunk:
tmp.write(chunk) # Write the chunk
tmp.flush()
# initialize File components of this object
file = File(tmp, name=name)
result.append(file)
return result
def cleanup(self):
'''
Removes any downloaded objects and closes open files.
'''
# self.file comes from Django File
if hasattr(self, 'file'):
if not self.file.closed:
self.file.close()
delattr(self, 'file')
if hasattr(self, 'filename'):
# the file might have been moved in the meantime so
# check first
if os.path.exists(self.filename):
os.remove(self.filename)
delattr(self, 'filename')
def __enter__(self):
'''
Allow FilepickerFile to be used as a context manager as such:
with FilepickerFile(url) as f:
model.field.save(f.name, f.)
'''
self.get_file()
# call Django's File context manager
return super(FilepickerFile, self).__enter__()
def __exit__(self, *args):
# call Django's File context manager
super(FilepickerFile, self).__exit__(*args)
self.cleanup()
def __del__(self):
self.cleanup()
Jump to Line
Something went wrong with that request. Please try again.