2011-04-12 12 views
11

Tengo un dilema .. Estoy cargando archivos tanto en scribd store como en blobstore usando tipfy como framework. Tengo un formulario web con acción no creado por blobstore.create_upload_url (solo estoy usando url_for ('myhandler')). Lo hice porque si estoy usando el manejador blobstore, la respuesta POST es analizada y no puedo usar python-scribd api normal para cargar archivos en scribd store. Ahora he trabajando protector de Scribd:¿Cómo escribir archivos grandes en Blobstore utilizando la API experimental?

class UploadScribdHandler(RequestHandler, BlobstoreUploadMixin): 
    def post(self): 
     uploaded_file = self.request.files.get('upload_file') 
     fname = uploaded_file.filename.strip() 
     try: 
      self.post_to_scribd(uploaded_file, fname) 
     except Exception, e: 
      # ... get the exception message and do something with it 
      msg = e.message 
      # ... 
     # reset the stream to zero (beginning) so the file can be read again 
     uploaded_file.seek(0) 
     #removed try-except to see debug info in browser window 
     # Create the file 

     file_name = files.blobstore.create(_blobinfo_uploaded_filename=fname) 
     # Open the file and write to it 
     with files.open(file_name, 'a') as f: 
      f.write(uploaded_file.read()) 
     # Finalize the file. Do this before attempting to read it.  
     files.finalize(file_name) 
     # Get the file's blob key 
     blob_key = files.blobstore.get_blob_key(file_name) 

     return Response('done') 

    def post_to_scribd(self, uploaded_file, fname): 
     errmsg ='' 
     uploaded_file = self.request.files.get('upload_file') 
     fname = uploaded_file.filename.strip() 
     fext = fname[fname.rfind('.')+1:].lower() 
     if (fext not in ALLOWED_EXTENSION): 
      raise Exception('This file type does not allowed to be uploaded\n') 
     if SCRIBD_ENABLED: 
      doc_title = self.request.form.get('title') 
      doc_description = self.request.form.get('description') 
      doc_tags = self.request.form.get('tags') 
      try: 
       document = scribd.api_user.upload(uploaded_file, fname, access='private') 
       #while document.get_conversion_status() != 'DONE': 
       # time.sleep(2) 
       if not doc_title: 
        document.title = fname[:fname.rfind('.')] 
       else: 
        document.title = doc_title 
       if not doc_description: 
        document.description = 'This document was uploaded at ' + str(datetime.datetime.now()) +'\n' 
       else: 
        document.description = doc_description 
       document.tags = doc_tags 
       document.save() 
      except scribd.ResponseError, err: 
       raise Exception('Scribd failed: error code:%d, error message: %s\n' % (err.errno, err.strerror)) 
      except scribd.NotReadyError, err: 
       raise Exception('Scribd failed: error code:%d, error message: %s\n' % (err.errno, err.strerror)) 
      except: 
       raise Exception('something wrong exception') 

Como se puede ver también guarda archivo en almacén de blob .. Pero si estoy de subir archivos grandes (es decir, 5Mb) Estoy recibiendo

RequestTooLargeError: The request to API call file.Append() was too large. 
Request: docs.upload(access='private', doc_type='pdf', file=('PK\x03\x04\n\x00\x00\x00\x00\x00"\x01\x10=\x00\x00(...)', 'test.pdf')) 

¿Cómo puedo arreglarlo? Gracias!

+0

¡Su pregunta y sus respuestas me han ayudado mucho, saludos! – selurvedu

Respuesta

7

Se necesitan hacer varias llamadas, más pequeños a la API de archivos, por ejemplo a esto:

with files.open(file_name, 'a') as f: 
    data = uploaded_file.read(65536) 
    while data: 
     f.write(data) 
     data = uploaded_file.read(65536) 

Tenga en cuenta que el límite de tamaño de carga útil en las solicitudes regulares a aplicaciones de App Engine es de 10 MB; si desea cargar archivos más grandes, deberá usar el mecanismo de carga de blobstore habitual.

+0

Usando su código de ejemplo, ¿puede pensar por qué daría un AttributeError - el objeto 'InMemoryUploadedFile' no tiene ningún atributo 'eof'? (En la segunda línea de tu ejemplo) – oldpal

+0

@bfox Presumiblemente porque no tiene ese atributo. Actualizaré mi respuesta con una alternativa. –

+0

@minus ¿Encontraste una solución a esto? Tengo el mismo problema que tú al intentar subir un archivo de 3-4 MB a la tienda de blob. –

6

finalmente encontré la solución.

La respuesta de Nick Johneson ha ocurrido un error de atributo porque archivo_cargado se trata como una cadena. cadena no tiene el método read().

Causa cadena no tiene el método read(), empalme una cadena de archivos y la escriba como lo escribió.

class UploadRankingHandler(webapp.RequestHandler): 
    def post(self): 
    fish_image_file = self.request.get('file') 

    file_name = files.blobstore.create(mime_type='image/png', _blobinfo_uploaded_filename="testfilename.png") 

    file_str_list = splitCount(fish_image_file,65520) 

    with files.open(file_name, 'a') as f: 
     for line in file_str_list: 
     f.write(line) 

puede consultar sobre splitCount(). aquí

http://www.bdhwan.com/entry/gaewritebigfile

Cuestiones relacionadas