def temp_uploaded_file(file): file_size = os.path.getsize(file.name) file_content = file.read() temp = TemporaryUploadedFile(file.name, 'text', file_size, None) temp.write(file_content) temp.seek(0) return temp
def validate_file_link(self, value): if not value: return r = requests.head(value, allow_redirects=True) headers = r.headers mime_type = headers.get('content-type') file_size = headers.get('content-length') file_name = None if "Content-Disposition" in r.headers.keys(): file_name_list = re.findall("filename=(.+)", r.headers["Content-Disposition"]) if len(file_name_list) > 0: file_name = file_name_list[0] if not file_name: file_name = value.split("/")[-1] tf = TemporaryUploadedFile( file_name, mime_type, file_size, 'utf-8' ) r = requests.get(value, stream=True) for chunk in r.iter_content(chunk_size=4096): tf.write(chunk) tf.seek(0) self._file = tf
class TemporaryFileUploadHandler(FileUploadHandler): """ Upload handler that streams data into a temporary file. """ def __init__(self, *args, **kwargs): super(TemporaryFileUploadHandler, self).__init__(*args, **kwargs) def new_file(self, file_name, *args, **kwargs): """ Create the file object to append to as data is coming in. """ super(TemporaryFileUploadHandler, self).new_file( file_name, *args, **kwargs) self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra) def receive_data_chunk(self, raw_data, start): self.file.write(raw_data) def file_complete(self, file_size): self.file.seek(0) self.file.size = file_size return self.file
class TemporaryFileUploadHandler(FileUploadHandler): """ Upload handler that streams data into a temporary file. """ def new_file(self, *args, **kwargs): """ Create the file object to append to as data is coming in. """ super().new_file(*args, **kwargs) self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra) def receive_data_chunk(self, raw_data, start): self.file.write(raw_data) def file_complete(self, file_size): self.file.seek(0) self.file.size = file_size return self.file def upload_interrupted(self): if hasattr(self, 'file'): temp_location = self.file.temporary_file_path() try: self.file.close() os.remove(temp_location) except FileNotFoundError: pass
def decorate(request, *args, **kwargs): if request.method == 'POST' and 'HTTP_X_FILE_NAME' in request.META: tf = TemporaryUploadedFile('rawdata', request.META['HTTP_X_FILE_TYPE'], int(request.META['CONTENT_LENGTH']), None) chunk = ' ' while len(chunk) > 0: chunk = request.read(1024) tf.write(chunk) tf.seek(0) request.FILES['file'] = tf return func(request, *args, **kwargs)
def parse_distutils_request(request): """ Due to a bug in the Python distutils library, the request post is sent using \n as a separator instead of the \r\n that the HTTP spec demands. This breaks the Django form parser and therefore we have to write a custom parser. This bug was fixed in the Python 2.7.4 and 3.4: http://bugs.python.org/issue10510 """ body = request.body.decode('latin-1') if not body.endswith('\r\n'): sep = body.splitlines()[1] request.POST = QueryDict('', mutable=True) try: request._files = MultiValueDict() except Exception: pass for part in filter(lambda e: e.strip(), body.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception: continue if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers and headers['name'] == 'content': dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content.encode('utf-8')) dist.seek(0) request.FILES.appendlist('distribution', dist) else: request.POST.appendlist(headers["name"], content) else: request.FILES['distribution'] = request.FILES['content'] # Distutils sends UNKNOWN for empty fields (e.g platform) for key, value in request.POST.items(): if value == 'UNKNOWN': request.POST[key] = None
def parse_distutils_request(request): """ Due to a bug in the Python distutils library, the request post is sent using \n as a separator instead of the \r\n that the HTTP spec demands. This breaks the Django form parser and therefore we have to write a custom parser. This bug was fixed in the Python 2.7.4 and 3.4: http://bugs.python.org/issue10510 """ if not request.body.endswith('\r\n'): sep = request.body.splitlines()[1] request.POST = QueryDict('', mutable=True) try: request._files = MultiValueDict() except Exception: pass for part in filter(lambda e: e.strip(), request.body.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception: continue if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers and headers['name'] == 'content': dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist('distribution', dist) else: request.POST.appendlist(headers["name"], content) else: request.FILES['distribution'] = request.FILES['content'] # Distutils sends UNKNOWN for empty fields (e.g platform) for key, value in request.POST.items(): if value == 'UNKNOWN': request.POST[key] = None
def test_save_tempfile(self): with media_root(): storage = SafeFileSystemStorage() content = 'Hello world!' f = TemporaryUploadedFile(name='filename', content_type='text/plain', size=len(content), charset='utf-8') f.write(content) f.seek(0) name = storage.save('hello.txt', f) self.assertEqual(name, 'hello.txt') self.assertEqual(open(storage.path(name)).read(), content)
def create_photo_versions(sender, instance, **kwargs): """Create `PhotoVersion`` objects for the photo object defined by `instance`. A version is created for a bounding box defined by each PhotoSize instance. """ from photo.models import Photo, PhotoSize, PhotoVersion photo = instance ext = '.jpg' t = None try: pth = photo.image.path except NotImplementedError: from django.core.files.temp import NamedTemporaryFile t = NamedTemporaryFile(suffix=ext) ix = photo.image if ix.closed: # Reload from DB photo = Photo.objects.get(pk=photo.pk) ix = photo.image for d in ix.chunks(4000000): t.write(d) t.flush() t.seek(0) pth = t for size in PhotoSize.objects.all(): # Create a suitable filename. filename = '%s-%s-%s%s' % (photo.pk, uuid4().hex[::7], slugify(size.name)[:10], ext) ctype = guess_type(filename)[0] temp_file = TemporaryUploadedFile(name=filename, content_type=ctype, size=0, charset=None) if t: t.seek(0) try: version = PhotoVersion.objects.get(photo=photo, size=size) remove_model_image(version, 'image') version.image = None except PhotoVersion.DoesNotExist: version = PhotoVersion(photo=photo, size=size) if size.do_crop: resize_to, crop_box, input_image = get_perfect_fit_resize_crop(size.bounding_box, (photo.width, photo.height)) else: resize_to = size.bounding_box crop_box = None # Resize to a temporary location. resize(pth, resize_to, out_file_path=temp_file, crop=crop_box) # Save resized copy to `version` instance. temp_file.seek(0) # Prepare file for a re-read. version.image.save(name=filename, content=temp_file, save=True) temp_file.close() if t: t.close()
class CustomFileUploadHandler(FileUploadHandler): """ Custom file upload handler which handles the file upload as job and can be stopped midway if the job is revoked. Acts mainly as a TemporaryFileUpload with additional logic. """ # TODO:Logging file progress def new_file(self, *args, **kwargs): super().new_file(*args, **kwargs) self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra) job = JobModel.objects.get(job_id=self.request.GET["job_id"]) job.job_status = JobModel.STARTED job.save() def receive_data_chunk(self, raw_data, start): # Depending on the job id the task handling will stop # midway if the status is 'REVOKED' time.sleep(0.5) try: job = JobModel.objects.get(job_id=self.request.GET["job_id"]) print(job) except JobModel.DoesNotExist: raise StopUpload(connection_reset=True) if job.job_status == JobModel.PAUSED: pulse_try = 0 while (job.job_status == JobModel.PAUSED and pulse_try <= settings.PULSE_MAX_TRIES): pulse_try += 1 time.sleep(settings.PAUSE_PULSE) job = JobModel.objects.get(job_id=self.request.GET["job_id"]) if pulse_try == settings.PULSE_MAX_TRIES: job.delete() job.save() raise StopUpload(connection_reset=True) elif job.job_status == JobModel.REVOKED: job.delete() raise StopUpload(connection_reset=True) self.file.write(raw_data) def file_complete(self, file_size): # delete the job after completion job = JobModel.objects.get(job_id=self.request.GET["job_id"]) job.delete() self.file.seek(0) self.file.size = file_size return self.file
def upload_file(url, timeout=5): """ Загрузка файла по урлу во временный файл. Пример: from libs.upload import * ... try: uploaded_file = upload_file('http://host.ru/image.jpg') except URLError as e: return JsonResponse({ 'message': str(e.msg), }, status=e.code) request.user.avatar.save(uploaded_file.name, uploaded_file, save=False) uploaded_file.close() try: request.user.full_clean() except ValidationError as e: request.user.avatar.delete(save=False) return JsonResponse({ 'message': ', '.join(e.messages), }, status=400) else: request.user.save() """ logger.debug('Uploading %s...', url) with contextlib.closing(urlopen(url, timeout=timeout)) as fp: headers = fp.info() file_name = url.split('/')[-1] content_type = headers.get('content-type') file_size = headers.get('content-length') charset = 'utf-8' tmp = TemporaryUploadedFile(file_name, content_type, file_size, charset, {}) while True: block = fp.read(8 * 1024) if not block: break tmp.write(block) logger.debug('Uploaded %s to file %s', url, tmp.file.name) tmp.seek(0) tmp.flush() return tmp
def parse_distutils_request(request): """Parse the `request.raw_post_data` and return a `MultiValueDict` for the POST data and the FILES data. This method is taken from the chishop source. """ try: sep = request.raw_post_data.splitlines()[1] except: raise ValueError('Invalid post data') request.POST = QueryDict('', mutable=True) try: request._files = MultiValueDict() except Exception: pass for part in filter(lambda e: e.strip(), request.raw_post_data.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception: continue if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers and headers['name'] == 'content': dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist('distribution', dist) else: # Distutils sends UNKNOWN for empty fields (e.g platform) # [[email protected]] if content == 'UNKNOWN': content = None request.POST.appendlist(headers["name"], content)
def parse_distutils_request(request): """ This is being used because the built in request parser that Django uses, django.http.multipartparser.MultiPartParser is interperting the POST data incorrectly and/or the post data coming from distutils is invalid. One portion of this is the end marker: \r\n\r\n (what Django expects) versus \n\n (what distutils is sending). """ sep = request.body.splitlines()[1] request.POST = QueryDict('', mutable=True) try: request._files = MultiValueDict() except Exception: pass for part in filter(lambda e: e.strip(), request.body.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception: continue try: if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers: dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist(headers['name'], dist) else: request.POST.appendlist(headers["name"], content) except Exception as e: print e return
def parse_distutils_request(request): """Parse the `request.raw_post_data` and update the request POST and FILES attributes . """ lines = request.raw_post_data.splitlines() seperator = next(line for line in lines if line.startswith('----')) request.POST = QueryDict('', mutable=True) raw_post = request.raw_post_data.split(seperator) raw_lines = [line.lstrip() for line in raw_post if line.lstrip()] try: request._files = MultiValueDict() except Exception: pass for line in raw_lines: line_content = line.lstrip().split('\n', 1) header = line_content[0] content = line_content[1] if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers and headers['name'] == 'content': dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist('distribution', dist) else: # Distutils sends UNKNOWN for empty fields (e.g platform) # [[email protected]] if content == 'UNKNOWN': content = None request.POST.appendlist(headers["name"], content)
def parse_distutils_request(request): """Parse the `request.raw_post_data` and update the request POST and FILES attributes . """ try: sep = request.raw_post_data.splitlines()[1] except: raise ValueError('Invalid post data') request.POST = QueryDict('', mutable=True) try: request._files = MultiValueDict() except Exception: pass for part in filter(lambda e: e.strip(), request.raw_post_data.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception: continue if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = parse_header(header) if "name" not in headers: continue if "filename" in headers and headers['name'] == 'content': dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist('distribution', dist) else: # Distutils sends UNKNOWN for empty fields (e.g platform) # [[email protected]] if content == 'UNKNOWN': content = None request.POST.appendlist(headers["name"], content)
def clean(self, value): url = super(ImageFromURLField, self).clean(value) if url: wf = urllib.urlopen(url) if wf.headers.getmaintype() != 'image': raise forms.ValidationError(u'Enter a URL for a valid image.') importedFile = TemporaryUploadedFile( url.split('/')[-1], wf.headers.gettype(), int(wf.headers.get('Content-Length')), None) importedFile.write(wf.read()) wf.close() importedFile.seek(0) if not is_valid_image(importedFile): raise forms.ValidationError(u'Enter a URL for a valid image.') return importedFile return url
def clean(self, value): url = super(ImageFromURLField, self).clean(value) if url: wf = urllib.urlopen(url) if wf.headers.getmaintype() != "image": raise forms.ValidationError(u"Enter a URL for a valid image.") importedFile = TemporaryUploadedFile( url.split("/")[-1], wf.headers.gettype(), int(wf.headers.get("Content-Length")), None ) importedFile.write(wf.read()) wf.close() importedFile.seek(0) if not is_valid_image(importedFile): raise forms.ValidationError(u"Enter a URL for a valid image.") return importedFile return url
def upload_report(cls, report): formats = ['pdf', 'xml'] try: for format in formats: if format == 'pdf': report_url = report.pdf_url else: report_url = report.xml_url request = requests.get(report_url, stream=True) filename = "appointment_%s_report.%s" % ( report.integrator_response.object_id, format) lf = TemporaryUploadedFile(filename, 'byte', 1000, 'utf-8') for block in request.iter_content(1024 * 8): # If no more file then stop if not block: break # Write image block to temporary file lf.write(block) lf.seek(0) lf.content_type = "application/%s" % format in_memory_file = InMemoryUploadedFile(lf, None, filename, lf.content_type, lf.tell(), None) lab_report, created = LabReport.objects.update_or_create( appointment_id=report.integrator_response.object_id) if lab_report: LabReportFile.objects.create(report_id=lab_report.id, name=in_memory_file) # Send Reports to Patient from ondoc.notification.tasks import send_lab_reports if format == 'pdf': try: send_lab_reports.apply_async( (report.integrator_response.object_id, ), countdown=1) except Exception as e: logger.error(str(e)) except Exception as e: logger.error(str(e))
class TemporaryFileUploadHandler(FileUploadHandler): """ Upload handler that streams data into a temporary file. """ def new_file(self, *args, **kwargs): """ Create the file object to append to as data is coming in. """ super().new_file(*args, **kwargs) self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra) def receive_data_chunk(self, raw_data, start): self.file.write(raw_data) def file_complete(self, file_size): self.file.seek(0) self.file.size = file_size return self.file
class AjaxFileUploadSessionMiddleware(object): chunk_size = 64 * 2 ** 10 # The default chunk size is 64 KB. def process_request(self, request): file_name = request.META.get('HTTP_X_FILE_NAME') self.uploaded_file = None if ('application/octet-stream' in request.META.get('CONTENT_TYPE') and request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' and request.method == 'POST' and file_name): initial_size = request._stream.remaining self.uploaded_file = TemporaryUploadedFile( name=unquote(file_name), content_type='application/octet-stream', size=initial_size, charset=None) size = 0 while True: chunk = request._stream.read(self.chunk_size) if not chunk: break size += len(chunk) self.uploaded_file.write(chunk) if size != initial_size: raise HttpResponseBadRequest self.uploaded_file.seek(0) self.uploaded_file.size = size request.FILES['file'] = self.uploaded_file request.POST = request.GET def process_response(self, request, response): if hasattr(self, 'uploaded_file') and self.uploaded_file is not None: tmp_file_name = self.uploaded_file.file.name if os.path.exists(tmp_file_name): os.remove(tmp_file_name) return response
def test_rack_form_clean_photo(self): from fixcity.exif_utils import get_exif_info from PIL import Image import os.path data = self.data.copy() # Jump through a few hoops to simulate a real upload. HERE = os.path.abspath(os.path.dirname(__file__)) path = os.path.join(HERE, 'files', 'test_exif.jpg') content = open(path).read() photofile = TemporaryUploadedFile('test_exif.jpg', 'image/jpeg', len(content), None) photofile.write(content) photofile.seek(0) # Okay, now we have something like a file upload. data['photo'] = photofile form = RackForm(data, {'photo': photofile}) self.assert_(form.is_valid()) # Make sure it doesn't have a bad rotation. self.assertEqual({}, get_exif_info(Image.open(photofile.temporary_file_path())))
def share(self, msgfile): msg = email.message_from_file(msgfile) args = {} files = [] check = getattr(settings, 'EMAIL2POST_CHECK', {}) for lhs in check: v = six.text_type(make_header(decode_header(msg.get(lhs, '')))) if not check[lhs] in v: return 77 # EX_NOPERM if msg.is_multipart(): for part in msg.walk(): attach = False t = part.get_content_type() if t == 'text/plain': if part.get_filename(None): attach = True else: args['content'] = part.get_payload(decode=True) if attach or \ t.startswith ('image/') or \ t.startswith ('audio/') or \ t.startswith ('video/') or \ t.startswith('application/'): payload = part.get_payload(decode=True) os.umask(0) tmp = TemporaryUploadedFile( name=part.get_filename('attachment'), content_type=t, size=len(payload), charset=None) tmp.write(payload) tmp.seek(0) os.chmod(tmp.file.name, 0o644) files.append(tmp) else: args['content'] = msg.get_payload(decode=True) subject = msg.get('Subject', None) if subject: hdr = make_header(decode_header(subject)) args['title'] = six.text_type(hdr) # Mail subject may contain @foo, a selfposts' class name for which # this message is post to. m = re.search(r'(\A|\s)@(\w[\w\-]+)', args['title']) if m: cls = m.groups()[1] args['title'] = re.sub(r'(\A|\s)@(\w[\w\-]+)', '', args['title']) s = Service.objects.filter(cls=cls, api='selfposts').values('id') if len(s): args['id'] = s[0]['id'] # Mail subject may contain "!draft" literal. if '!draft' in args['title']: args['title'] = args['title'].replace('!draft', '').strip() args['draft'] = True # Mail subject may contain "!friends-only" literal. if '!friends-only' in args['title']: args['title'] = args['title'].replace( '!friends-only', '').strip() args['friends_only'] = True if len(files): args['files'] = MultiValueDict() args['files'].setlist('docs', files) selfposts.API(None).share(args) return 0 # EX_OK
"""
pass for part in filter(lambda e: e.strip(), request.body.split(sep)): try: header, content = part.lstrip().split('\n', 1) except Exception, e: continue if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] headers = _parse_header(header) if "name" not in headers: continue if "filename" in headers: dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist(headers['name'], dist) else: request.POST.appendlist(headers["name"], content) return
def share(self, msgfile): msg = email.message_from_file(msgfile) args = {} files = [] check = getattr(settings, 'EMAIL2POST_CHECK', {}) for lhs in check: v = six.text_type(make_header(decode_header(msg.get(lhs, '')))) if not check[lhs] in v: return 77 # EX_NOPERM if msg.is_multipart(): for part in msg.walk(): attach = False t = part.get_content_type() if t == 'text/plain': if part.get_filename(None): attach = True else: args['content'] = part.get_payload(decode=True) if attach or \ t.startswith ('image/') or \ t.startswith ('audio/') or \ t.startswith ('video/') or \ t.startswith('application/'): payload = part.get_payload(decode=True) os.umask(0) tmp = TemporaryUploadedFile( name=part.get_filename('attachment'), content_type=t, size=len(payload), charset=None) tmp.write(payload) tmp.seek(0) os.chmod(tmp.file.name, 0o644) files.append(tmp) else: args['content'] = msg.get_payload(decode=True) subject = msg.get('Subject', None) if subject: hdr = make_header(decode_header(subject)) args['title'] = six.text_type(hdr) # Mail subject may contain @foo, a selfposts' class name for which # this message is post to. m = re.search(r'(\A|\s)@(\w[\w\-]+)', args['title']) if m: cls = m.groups()[1] args['title'] = re.sub(r'(\A|\s)@(\w[\w\-]+)', '', args['title']) s = Service.objects.filter(cls=cls, api='selfposts').values('id') if len(s): args['id'] = s[0]['id'] # Mail subject may contain "!draft" literal. if '!draft' in args['title']: args['title'] = args['title'].replace('!draft', '').strip() args['draft'] = True # Mail subject may contain "!friends-only" literal. if '!friends-only' in args['title']: args['title'] = args['title'].replace('!friends-only', '').strip() args['friends_only'] = True if len(files): args['files'] = MultiValueDict() args['files'].setlist('docs', files) selfposts.API(None).share(args) return 0 # EX_OK
# newer distutils can submit \r\n end-of-line marks. if header.endswith('\r'): header = header[:-1] if content.startswith('\r'): content = content[1:] if content.startswith('\n'): content = content[1:] if content.endswith('\n'): content = content[:-1] if content.endswith('\r'): content = content[:-1] headers = _parse_header(header) if "name" not in headers: continue if "filename" in headers: dist = TemporaryUploadedFile(name=headers["filename"], size=len(content), content_type="application/gzip", charset='utf-8') dist.write(content) dist.seek(0) request.FILES.appendlist(headers['name'], dist) else: request.POST.appendlist(headers["name"],content) return
def upload_chunked_file(request, param_name, allow_memory=True): """ Загрузчик файлов, переданных от форм. Поддерживает передачу файла по частям. Возвращает обертку над файлом (возможно в памяти), удаляющимся после закрытия. Если allow_memory = False, то мелкие файлы, которые Django сохраняет в память, будут принудительно сохранены во временные файлы на диске. Пример: from libs.upload import upload_chunked_file, NotLastChunk, TemporaryFileNotFoundError ... try: uploaded_file = upload_chunked_file(request, 'image') except TemporaryFileNotFoundError as e: return JsonResponse({ 'message': str(e), }, status=400) except NotLastChunk: return HttpResponse() request.user.avatar.save(uploaded_file.name, uploaded_file, save=False) uploaded_file.close() try: request.user.avatar.field.clean(request.user.avatar, request.user) except ValidationError as e: request.user.avatar.delete(save=False) return JsonResponse({ 'message': ', '.join(e.messages), }, status=400) request.user.avatar.clean() request.user.avatar.save() """ file = request.FILES[param_name] chunk_num = int(request.POST.get('chunk', 0)) chunk_count = int(request.POST.get('chunks', 1)) if chunk_count == 1: # файл одним куском if not isinstance(file, InMemoryUploadedFile): return file elif allow_memory: return file else: # принудительное сохранение в файл tmp = TemporaryUploadedFile(file.name, file.content_type, file.size, file.charset, file.content_type_extra) for chunk in file.chunks(): tmp.write(chunk) tmp.seek(0) tmp.flush() return tmp else: # pluploader отправляет имя "blob" file.name = os.path.basename(request.POST.get('name', file.name)) # генерируем имя, которое можно восстановить при получении # следующих чанков name, ext = os.path.splitext(file.name) hashname = '%s.%s' % (request.META.get('REMOTE_ADDR'), name) hashname = hashlib.md5(hashname.encode()).hexdigest() tempfile_name = '%s.upload%s' % (hashname, ext) tempfile_path = os.path.join(tempfile.gettempdir(), tempfile_name) if chunk_num > 0: if not os.path.exists(tempfile_path): raise TemporaryFileNotFoundError(_('Temporary file lost')) tmp = open(tempfile_path, 'ab+') if chunk_num == 0: tmp.seek(0) tmp.truncate() for chunk in file.chunks(): tmp.write(chunk) if chunk_num < chunk_count - 1: tmp.close() raise NotLastChunk(chunk_num + 1, chunk_count) tmp.seek(0) tmp.flush() file_info = os.stat(tempfile_path) return TempUploadedFile(tmp, name=file.name, content_type=file.content_type, size=file_info.st_size, charset=file.charset, content_type_extra=file.content_type_extra)
class UploadProgressCachedHandler(FileUploadHandler): """ Tracks progress for file uploads. The http post request must contain a header or query parameter, 'X-Progress-ID', which should contain a unique string to identify the upload to be tracked. Copied from: http://djangosnippets.org/snippets/678/ See views.py for upload_progress function... """ def __init__(self, request=None): super(UploadProgressCachedHandler, self).__init__(request) self.progress_id = None self.cache_key = None def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None): """ """ self.content_length = content_length if 'X-Progress-ID' in self.request.GET: self.progress_id = self.request.GET['X-Progress-ID'] elif 'X-Progress-ID' in self.request.META: self.progress_id = self.request.META['X-Progress-ID'] if self.progress_id: self.cache_key = "%s_%s" % ( self.request.META['REMOTE_ADDR'], self.progress_id ) cache.set(self.cache_key, { 'length': self.content_length, 'uploaded': 0 }) def new_file(self, field_name, file_name, content_type, content_length, charset=None): """ """ self.field_name = field_name self.file_name = file_name self.content_type = content_type self.content_length = content_length self.charset = charset self.file = TemporaryUploadedFile( self.file_name, self.content_type, 0, self.charset ) def receive_data_chunk(self, raw_data, start): """ """ if self.cache_key: data = cache.get(self.cache_key) data['uploaded'] += self.chunk_size cache.set(self.cache_key, data) self.file.write(raw_data) return raw_data def file_complete(self, file_size): """ """ self.file.seek(0) self.file.size = file_size self.file.close() return self.file def upload_complete(self): """ """ if self.cache_key: cache.delete(self.cache_key)