Skip to content

Instantly share code, notes, and snippets.

@Quard
Created February 8, 2012 06:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Quard/1766187 to your computer and use it in GitHub Desktop.
Save Quard/1766187 to your computer and use it in GitHub Desktop.
Widget for upload file/image by selecting from local disk or from URL
import urlparse
import httplib
from copy import copy
try:
from cStringIO import StringIO
except:
from StringIO import StringIO
from django import forms
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile
from django.utils.safestring import mark_safe
class FileURLInput(forms.FileInput):
def _get_field_file_name(self, name):
return u'%s_file' % name
def _get_field_url_name(self, name):
return u'%s_url' % name
def render(self, name, value, attrs=None):
attrs_file = copy(attrs)
attrs_file['id'] = '%s_file' % attrs_file['id']
attrs_url = copy(attrs)
attrs_url['type'] = 'text'
attrs_url['id'] = '%s_url' % attrs_url['id']
return mark_safe('\n'.join((
super(FileURLInput, self).render(
self._get_field_file_name(name),
None,
attrs=attrs_file
),
super(FileURLInput, self).render(
self._get_field_url_name(name),
None,
attrs=attrs_url
),
)))
def value_from_datadict(self, data, files, name):
if self._get_field_file_name(name) in files:
return files.get(self._get_field_file_name(name), None)
elif data.get(self._get_field_url_name(name)):
url = urlparse.urlparse(
data.get(self._get_field_url_name(name), None)
)
conn = None
if url.scheme == 'http':
conn = httplib.HTTPConnection(url.netloc)
elif url.scheme == 'https':
conn = httplib.HTTPSConnection(url.netloc)
conn.request('GET', url.geturl())
resp = conn.getresponse()
if resp.status != 200:
return File(StringIO())
fl = NamedTemporaryFile(delete=True)
fl.write(resp.read())
fl.flush()
fl.seek(0)
return File(fl, name=url.path.rsplit('/', 1)[-1])
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment