В приложении django я использую сторонний Python script , чтобы позволить пользователям загружать файлы в blip.tv через httplib.HTTPConnection.send на экземпляре EC2. Поскольку эти файлы обычно имеют большой размер, я буду использовать очередь сообщений для асинхронной обработки загрузки (RabbitMQ / Celery) и сообщать о ходе работы пользователю во внешнем интерфейсе.
httpconnection и send выполняются в этой части скрипта:
host, selector = urlparts = urlparse.urlsplit(url)[1:3]
h = httplib.HTTPConnection(host)
h.putrequest("POST", selector)
h.putheader("content-type", content_type)
h.putheader("content-length", len(data))
h.endheaders()
h.send(data)
response = h.getresponse()
return response.status, response.reason, response.read()
Функция getresponse () возвращается после завершения передачи файла. Как мне записать ход выполнения (предположим, что-то с помощью stdout.write), чтобы я мог записать это значение в структуру кэша для отображения (djangosnippets 678/679)? В качестве альтернативы, если есть лучшая практика для этого, я весь слух!
EDIT:
Поскольку я использовал urllib2 и использовал подсказку из этого вопроса , чтобы переопределить read () файла, чтобы получить ход загрузки. Кроме того, я использую плакат для генерации многочастного urlencode. Вот последний код:
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
def Upload(video_id, username, password, title, description, filename):
class Progress(object):
def __init__(self):
self._seen = 0.0
def update(self, total, size, name):
self._seen += size
pct = (self._seen / total) * 100.0
print '%s progress: %.2f' % (name, pct)
class file_with_callback(file):
def __init__(self, path, mode, callback, *args):
file.__init__(self, path, mode)
self.seek(0, os.SEEK_END)
self._total = self.tell()
self.seek(0)
self._callback = callback
self._args = args
def __len__(self):
return self._total
def read(self, size):
data = file.read(self, size)
self._callback(self._total, len(data), *self._args)
return data
progress = Progress()
stream = file_with_callback(filename, 'rb', progress.update, filename)
datagen, headers = multipart_encode({
"post": "1",
"skin": "xmlhttprequest",
"userlogin": "%s" % username,
"password": "%s" % password,
"item_type": "file",
"title": "%s" % title.encode("utf-8"),
"description": "%s" % description.encode("utf-8"),
"file": stream
})
opener = register_openers()
req = urllib2.Request(UPLOAD_URL, datagen, headers)
response = urllib2.urlopen(req)
return response.read()
Это работает только для входных файловых путей, а не для InMemoryUploadedFile, который поступает из входных данных формы (request.FILES), так как он пытается прочитать файл, уже сохраненный в памяти, я полагаю, и я получаю TypeError в строке : "stream = file_with_callback (имя файла, 'rb', progress.update, имя файла)":
coercing to Unicode: need string or buffer, InMemoryUploadedFile found
Как я могу добиться того же отчета о проделанной работе с загруженным пользователем файлом? Кроме того, будет ли это занимать много памяти при чтении процесса, подобного этому, возможно, решение для загрузки этого процесса загрузки для urllib2 будет работать лучше, но как реализовать ... Справка ооочень приветствуется