LINUX.ORG.RU

upload на bottlepy


0

1

Подскажите как сделать на сабже upload файлов, выполнить с ними какие-то действия и отдать результат клиенту. Например загружаем в форму аплоада рисунок/рисунки, затем сервер делает ресайз рисунка/рисунков и отдает клиенту. Почему bottlepy? Видимо потому что он простой как двери, для начала думаю хватит с головой.

просто демонстрация, в продакшен такое пихать не нужно

from bottle import get, post, static_file, run
from StringIO import StringIO
import Image

@get('/upload')
def upload_form():
    return '''
<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="image" /><br />
  <input type="submit" />
</form>
    '''

@post('/upload')
def upload_submit():
    imageFile = request.files.image
    im = Image.open(StringIO(imageFile.file.read()))
    im.thumbnail((128,128), Image.ANTIALIAS)
    im.save('name.png')

    return static_file('name.png',root='./')

run(host='localhost', port=8080, debug=True)
beka
()
Ответ на: комментарий от one_quaker

Спасибо тебе добрый человек, код работает

не за что! работать-то работает, но я имел в виду, что стоит обратить внимание еще на то, что:
а) html в python-e => фууу ;)
б) нигде не смотрится, передается ли в форме файл вообще («Юзер может вводить что угодно. Хоть стихи про гитлера на иврите в поле для целого числа» (c) metaclass)
в) нет никакого ограничения на размер файла, что тоже не очень хорошо
г) нет работы с исключениями, если вместо картинки передали файл другого формата
д) ну и по-хорошему не нужно редактировать картинку, прямо во время запроса. лучше сделать очередь таких картинок и обрабатывать их исходя из нагрузки(как в flickr-e сделано)

Есть джаббер чтобы позадавать нубовские вопросы?)

уже 2 года как не заходил в свой джаббер...

beka
()
Ответ на: комментарий от one_quaker

а) html в python-e => фууу ;)

запихни весь html код в шаблон и возвращай «return template(„filename“)» подробнее смотри сюда: http://bottlepy.org/docs/dev/tutorial.html#tutorial-templates

б) нигде не смотрится, передается ли в форме файл вообще («Юзер может вводить что угодно. Хоть стихи про гитлера на иврите в поле для целого числа» (c) metaclass)

если я просто нажму кнопку отправить без того, чтобы выбрать файл картинки, приложение выдаст ошибку 500, так как строка «im = Image.open(StringIO(imageFile.file.read()))» будеть кидать Exception. И надо бы удостоверится послал ли нам юзер файл или просто нажал на кнопку отправить. Поэтому перепишем upload_submit так:

@post('/upload')
def upload_submit():
    imageFile = request.files.image
    if hasattr(imageFile, 'file'):
        im = Image.open(StringIO(imageFile.file.read()))
        im.thumbnail((128,128), Image.ANTIALIAS)
        im.save('name.png')
        return static_file('name.png',root='./')

    return upload_form()

нет работы с исключениями, если вместо картинки передали файл другого формата

опять же, если вместо картинки передать текстовый документ, приложение выплюнет Exception, и Error 500 в этом месте: «Image.open()»

значит нужно добавить туда что-то вроде:

try:
    im = Image.open(StringIO(imageFile.file.read()))
except IOError:
    return u'Не нужно вместо картинки загружать что-то другое!!!111одинадин!'

Мылом хоть пользуешься?)

avoid.мой_ник_на_ЛОРЕ@gmail.com - только я до середины(15-16) февраля буду очень-очень-очень занят и вряд ли смогу что-то внятное ответить - после без проблем)

beka
()
Ответ на: комментарий от beka

Два чая этому господину.

В теории что нужно сделать я понял, осталось только понять как реализовать. В почту отписал.

one_quaker
() автор топика
Ответ на: комментарий от beka

Чет даже пример из туториала не работает. Если убрать if, тогда работает, но естественно нет проверки пустое поле или нет.

one_quaker
() автор топика
Ответ на: комментарий от beka

С формой и шаблоном вроде разобрался, как сделать ограничение на размер загружаемого файла и очередь?

one_quaker
() автор топика
Ответ на: комментарий от one_quaker

Чет даже пример из туториала не работает. Если убрать if, тогда работает, но естественно нет проверки пустое поле или нет.

Замени в примере из туториала «if name and data and data.file:» на «if name and hasattr(„file“, data):». Я не уверен, но это вроде не баг, а просто они привели пример, который работает только на apache + mod_python. В любом случае чтобы сказать наверняка надо залезть в исходный код, но к сожаленью сейчас нет на это времени.

как сделать ограничение на размер загружаемого файла

Подходов очень много, можно к примеру, использовать директиву LimitRequestBody, если в качестве сервера стоит Apache или client_max_body_size у Nginx`а. Хорошо бы на клиенте проверять размер файла(JavaScript, Flash или что-там собираешься использовать в качестве uploader`а). Можно даже проверить размер уже у загруженного файла в bottle.py: «if len(im) > размер_в_байтах: ...»

Если это личный блог, то можешь не делать проверку файлов, если же нагрузка будет, то лучше сделать проверку на клиента яваскриптом и одновременно директивой на сервере(LimitRequestBody/client_max_body_size), чтобы отбывать потенциальные DoS-атаки.

очередь

очередь, опять же, нужно сделать если будет нагрузка, а не просто личный блог. Технологии которые позволяют делать очереди много - ActiveMQ, RabbitMQ, ZeroMQ... Я, вообще, собственный велосипед на Erlang`e использую. Для питона есть канонический celery, что это и зачем можешь прочесть тут - http://vorushin.ru/blog/34-celery-described/

beka
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.