Получить статус загрузки в webpy - PullRequest
1 голос
/ 14 января 2012

Я создаю загрузчик для своего проекта и стараюсь избегать любых решений на основе флэш-памяти (мне не очень нравится флэш-память и я нацеливаюсь на поддержку мобильных платформ). Весь процесс кажется довольно простым: у меня есть форма, приятный индикатор выполнения jQuery, я могу делать ajax-запросы с тайм-аутом из скрипта для обновления статуса индикатора выполнения ... Если я делаю это в соответствии с кулинарной книгой Webpy, единственное, что я не получаю, это как получить какую-либо информацию с сервера: сколько байт / кусков / что бы там ни было уже написано?

1 Ответ

2 голосов
/ 15 января 2012

Вы можете создать загрузчик ajax, используя FormData для современных браузеров.

$.fn.uploader = function( options ) {
    var defaults = {},
        opts = $.extend( defaults, options ),
        that = $( this ),
        url = that.data( "upload_url" ),
        is_uploading = false;

    function upload( files ) {

        $.get( "/file/blank.html" );

        if ( FormData === undefined ) {
            alert( "Your browser does not support standard HTML5 Drag and Drop" );
            return;
        }        

        var xhr = new XMLHttpRequest(),
            new_element = $( "<li><p>Loading</p><span></span></li>" )
                .appendTo( that ),
            xhr_upload = xhr.upload,
            form = new FormData();

        xhr_upload.addEventListener( "progress", function( e ) {
            if( e.lengthComputable ) {
                var p = Math.round( e.loaded * 100 / e.total );
                new_element.children( "span" ).text( e.loaded == e.total ? "Processing..." : p + "%" );
            }
        }, false);
        xhr_upload.addEventListener( "load", function( e ){}, false);
        xhr_upload.addEventListener( "error", function( error ) { alert( "error: " + error ); }, false);

        xhr.open( "POST", url, true );
        xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest" );

        xhr.onreadystatechange = function ( e ) {
            if ( xhr.readyState == 4 ) {
                is_uploading = false;
                if( xhr.status == 200 ) {
                    var data = $.parseJSON( e.target.responseText );
                    if ( data.status == 0 ) {
                        new_element
                            .fadeOut(function (){ $( this ).remove(); })
                            .children( "span" ).text( "Upload error!" );
                    } else {
                        that.html( data.html );
                    }
                } else {
                    new_element
                        .fadeOut(function (){ $( this ).remove(); })
                        .children( "span" ).text( "Upload error!" );
                }
            }
        };
        $.each( files, function() {
            form.append( "files", this );
        });
        is_uploading = true;
        xhr.send( form );
    }

    that.bind({
        "dragover": function( e ) {
            var dt = e.originalEvent.dataTransfer;
            if( !dt || is_uploading ) { return; };
            if( $.browser.webkit ) { dt.dropEffect = "copy"; };
            $( this ).addClass( "active" );
            return false;
        },
        "dragleave": function( e ) {
            $( this ).removeClass( "active" );
        },
        "dragenter": function( e ){ return false; },
        "drop": function( e ){
            var dt = e.originalEvent.dataTransfer;
            $( this ).removeClass( "active" );
            if( !dt || !dt.files || is_uploading ) { return; };
            upload( dt.files );
            return false;
        }
    });

    $( document ).bind({
        'dragenter': function( e ) { return false; },
        'dragleave': function( e ) { return false; },
        'dragover': function( e ) {
            var dt = e.originalEvent.dataTransfer;
            if ( !dt ) { return; }
            dt.dropEffect = "none";
            return false;
        }
    });

};

На стороне сервера я обрабатываю его так:

def POST(self):
    i = web.webapi.rawinput()
    try:
        files = i.files
        if not isinstance(files, list):
            files = [files]
        for f in files:
            if f.filename:
                filetype, encoding = mimetypes.guess_type(f.filename)
                # do smth with f.file
    except KeyError:
        pass
    if web.ctx.env.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
        web.header("Content-Type", "application/json")
        return json.dumps(dict(status=1, html=unicode(render_partial.files(uploaded_files))))
    else:
        raise web.seeother(web.ctx.env.get("HTTP_REFERER", "/"))

В противном случае вы можете посмотреть модуль загрузки nginx модуль или модуль прогресса загрузки apache2, uWSGI также имеет эту функцию.

...