2011-09-06 13 views
10

Estoy usando la tienda de blobstore de Google App Engine para almacenar un rango de tipos de archivos (PDF, XLS, etc.) y estoy intentando encontrar un mecanismo por el cual el nombre original del archivo cargado tal como se almacena en blob_info: se puede usar para nombrar el archivo descargado, es decir, para que el usuario vea 'algún_archivo.pdf' en el diálogo de guardar en lugar de 'very_long_db_key.pdf'.Nombre de archivo descargado con Google App Engine Blobstore

no puedo ver nada en la documentación que permitiría a esto:

http://code.google.com/appengine/docs/python/blobstore/overview.html

que he visto indicios en otros mensajes que usted podría utilizar la información en blob_info para establecer la cabecera Content-Disposition . ¿Es este el mejor enfoque para lograr el fin deseado?

Respuesta

11

Hay un parámetro 'save_as' opcional en la función send_blob. Por defecto, esto está establecido en False. Establecerlo en True hará que el archivo se trate como un archivo adjunto (es decir, activará un cuadro de diálogo de descarga 'Guardar/Abrir') y el usuario verá el nombre de archivo correcto.

Ejemplo:

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler): 
    def get(self, resource): 
     resource = str(urllib.unquote(resource)) 
     blob_info = blobstore.BlobInfo.get(resource) 
     self.send_blob(blob_info,save_as=True) 

También es posible sobrescribir el nombre del archivo mediante introducción de una cadena:

self.send_blob(blob_info,save_as='my_file.txt') 

Si quieres algo de contenido (como archivos PDF) para que quede más que le ahorran podría usar content_type para determinar el comportamiento:

blob_info = blobstore.BlobInfo.get(resource) 
type = blob_info.content_type 
if type == 'application/pdf':  
    self.response.headers['Content-Type'] = type 
    self.send_blob(blob_info,save_as=False) 
else: 
    self.send_blob(blob_info,save_as=True) 
+0

Solo para agregar: si el nombre del archivo original contiene una comilla doble, el cuadro de diálogo de la descarga truncará el nombre del archivo después del carácter de comillas. Lo solucioné escapando comillas dobles en el nombre de archivo blob: 'self.send_blob (blob_info, save_as = blob_info.filename.replace ('"', '\\"')) ' (Hay una discusión relacionada sobre esto [aquí] (http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter -of-content-disposition-header-in-http)) –

0

Sí, es el mejor enfoque; solo consulte el objeto BlobInfo utilizando la clave de Blobstore determinada y use su propiedad content-type.

1

Otra opción es agregar el nombre del archivo al final de la URL de descarga. Por ejemplo:

/files/AMIfv95HJJY3F75v3lz2EeyvWIvGKxEcDagKtyDSgQSPWiMnE0C2iYTUxLZlFHs2XxnV_j1jdWmmKbSVwBj6lYT0-G_w5wENIdPKDULHqa8Q3E_uyeY1gFu02Iiw9xm523Rxk3LJnqHf9n8209t4sPEHhwVOKdDF2A/prezents-list.doc 

Si utiliza Jinja2 para crear plantillas, puede construir un enlace como este:

<a href="/files/{{blob_info.key()}}/{{blob_info.filename}}">{{file.filename}}</a> 

entonces usted debe adaptar su asignación de dirección URL correspondiente a algo como esto:

('/files/([^/]+)/?.*', DownloadHandler) 

Si tiene la clave de blob en la URL, puede ignorar el nombre del archivo en el código del lado del servidor.

El beneficio de este enfoque es que los tipos de contenido como imágenes o PDF se abren directamente en el navegador, lo que es conveniente para una visualización rápida. Otros tipos de contenido simplemente se guardarán en el disco.