Flask暂时存储分块文件,然后上传

时间:2019-09-15 06:05:50

标签: python flask dropzone.js pythonanywhere chunking

问题声明:我有一个烧瓶服务器托管在 pythonanywhere.com 中。我的网站所做的是,用户从我的网站上传zip文件(apk,ipa压缩),Flask将其下载,然后将其上传到对象存储。现在,无需分块zip文件(通常为60-70 mb),上传只需3-4分钟。经过一番搜索,我开始了解分块。对于前端部分,我正在使用javascript库进行分块:

 <form method="POST" enctype=multipart/form-data id="dropper">
    <label for="file"><span style="font-size: 20px">Enter package (ex: Sconnect_iOS_test_1_0_6.zip)</span></label>
    <input type=file name=file id="file" required onchange="checkName()">
    <script type="application/javascript">
    Dropzone.options.dropper = {
        paramName: 'file',
        chunking: true,
        forceChunking: true,
        url: '/upload',
        maxFilesize: 1025, // megabytes
        chunkSize: 1000000 // bytes
    }
</script>

因为我不想将文件永久存储在 pythonanywhere.com 服务器中,所以我不想使用

with open(save_path, 'ab') as f:
        f.seek(int(request.form['dzchunkbyteoffset']))
        f.write(file.stream.read())

所以,我尝试使用tempfile。但是尝试之后,服务器似乎对我很生气:(

<body><h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>
</body>

如何完成此任务。还需要注意的是,为了存储对象,对象存储供应商提供了python API进行分块和上传,但是对于下载部分,我却迷茫了。

这是我的代码:

fd, path = tempfile.mkstemp()

if request.form['btn'] == 'Upload' and g.user:
        if 'file' not in request.files:
            flash('No file part')
            return show_notification("oops, No file part")

        file = request.files['file']

        # assembling chunks ---------------------------------------->>>
        current_chunk = int(request.form['dzchunkindex'])

        # If the file already exists it's ok if we are appending to it,
        # but not if it's new file that would overwrite the existing one
        if os.path.exists(path) and current_chunk == 0:
            # 400 and 500s will tell dropzone that an error occurred and show an error
            return make_response(('File already exists', 400))

        try:
            with os.fdopen(fd, 'wb') as f:
                f.seek(int(request.form['dzchunkbyteoffset']))
                f.write(file.stream.read())
        except OSError:
            return make_response(("Not sure why,"
                                  " but we couldn't write the file to disk", 500))

        total_chunks = int(request.form['dztotalchunkcount'])

        if current_chunk + 1 == total_chunks:
            # This was the last chunk, the file should be complete and the size we expect
            if os.path.getsize(save_path) != int(request.form['dztotalfilesize']):
                return make_response(('Size mismatch', 500))
            else:
                with os.fdopen(fd, 'rb') as fb:
                    fb.seek(0, os.SEEK_END)
                    size = fb.tell()
                    # seek to its beginning, so you might save it entirely
                    fb.seek(0)
                    # if user does not select file, browser also
                    # submit an empty part without filename
                    if file.filename == '':
                        flash('No selected file')
                        return show_notification("oops, No file selected!")
                    if file and allowed_file(file.filename):
                        filename = secure_filename(file.filename)
                        #print(filename, [temp[1] for temp in file_exist])
                        if filename in [temp[1] for temp in file_exist]:
                            return show_notification("oops, file name already exists!")
                        elif request.form['version'] in [temp[2] for temp in file_exist]:
                            return show_notification("oops, version already exists!")
                        elif request.form['version'].strip() == '':
                            return show_notification("oops, version should not be empty!")
                        else:
                            try:
                                multi_part_upload_manual("bucketname", filename, fb, size)
                                os.remove(path)
                                try:
                                    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                                    cur.execute("some sql command")
                                    name = cur.fetchall()[0][0]
                                    cur.execute("some sql command")
                                    mysql.connection.commit()
                                    return show_notification('Upload successful!!')

                                except Exception as e:
                                    print(e)
                                    return show_notification('Upload unsuccessful!!<br>'+str(e))


                            except Exception as e:
                                return show_notification('Upload unsuccessful!!<br>'+str(e))
                                os.remove(path)

                    os.remove(path)
                    return show_notification('oops, unsupported file format!')

        else:

            print('Chunk {} of {} for file {}complete'.format(current_chunk1,total_chunks,file.filename))

        return make_response(("Chunk upload successful", 200))
        #assembling chunks ----------------------------------->>>

请帮助我,如何解决它,否则,我必须求助于不要分块上传:(

0 个答案:

没有答案