2011-09-06 3 views
10

sto usando il Google App Engine blobstore per memorizzare una vasta gamma di tipi di file (PDF, XLS, ecc) e sto cercando di trovare un meccanismo attraverso il quale il nome originale del file caricato - come memorizzato in blob_info - può essere usato per dare un nome al file scaricato, cioè in modo che l'utente veda 'some_file.pdf' nel dialogo di salvataggio piuttosto che 'very_long_db_key.pdf'.nome del file scaricati con Google App Engine blobstore

io non riesco a vedere nulla nella documentazione che permetterebbe questo:

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

Ho visto osservazioni in altri post che è possibile utilizzare le informazioni in blob_info per impostare l'intestazione Content-Disposition . È questo l'approccio migliore per raggiungere la fine desiderata?

risposta

11

C'è un parametro opzionale 'Save_as' nella funzione send_blob. Di default questo è impostato su False. Impostandolo su True, il file verrà considerato come un allegato (ovvero attiverà una finestra di dialogo "Salva/apri") e l'utente vedrà il nome file corretto.

Esempio:

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) 

E 'anche possibile sovrascrivere il nome del file passando una stringa:

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

Se volete un po' di contenuti (come ad esempio i PDF) per aprire piuttosto che risparmiare potrebbe utilizzare il content_type per determinare il comportamento:

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 aggiungere - se il nome del file originale contiene un doppio apice, la finestra di download troncare il nome del file dopo il carattere preventivo. Ho intorno a questo fuggendo virgolette nel nome del file blob: 'self.send_blob (blob_info, Save_as = blob_info.filename.replace ('"' ',' \\" ')) ' (C'è una discussione correlata su questo [qui] (http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter -of-content-disposition-header-in-http)) –

0

Sì, è l'approccio migliore; basta interrogare l'oggetto BlobInfo usando la chiave Blobstore e usare la sua proprietà content-type.

1

per riferimento futuro, Save_as e la BlobstoreDownloadHandler è documentato qui:

http://code.google.com/appengine/docs/python/tools/webapp/blobstorehandlers.html

Sembra come dovrebbe essere un po 'più facile da trovare. Vediamo se può essere migliorato.

+0

Sì, l'ho visto una volta che la risposta era stata segnalata. send_blob sembra mancare anche del materiale di riferimento: http://code.google.com/appengine/docs/python/blobstore/overview.html – notreadbyhumans

1

Un'altra opzione è quella di aggiungere il nome del file alla fine della URL di download. Per esempio:

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

Se si utilizza Jinja2 per template, è possibile costruire un tale URL come questo:

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

allora si dovrebbe adattare la mappatura URL di conseguenza per qualcosa di simile:

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

Se si dispone della chiave blob nell'URL, è possibile ignorare il nome del file nel codice lato server.

Il vantaggio di questo approccio è che i tipi di contenuti come immagini o PDF si aprono direttamente nel browser, che è conveniente per la visualizzazione rapida. Altri tipi di contenuto verranno semplicemente salvati sul disco.