Question

Je prévois de créer une application Web permettant aux utilisateurs de rétrograder leurs fichiers de projet Visual Studio. Cependant, il semble que Google App Engine accepte le téléchargement de fichiers et le stockage de fichiers à plat sur le serveur Google via db.TextProperty et db.BlobProperty.

Je serais heureux que tout le monde puisse fournir un exemple de code (côté client et côté serveur) sur la manière de procéder.

Était-ce utile?

La solution

Voici un fichier complet et fonctionnel. J'ai extrait l'original du site Google et l'ai modifié pour le rendre légèrement plus réaliste.

Quelques points à noter:

  1. Ce code utilise API BlobStore
  2. Le but de cette ligne dans le La classe ServeHandler doit & Quot; réparer & Quot; le clé pour qu'il se débarrasse de tout nom malheurs qui peuvent avoir eu lieu dans le navigateur (je n’en ai observé aucun dans Chrome)

    blob_key = str(urllib.unquote(blob_key))
    
  3. Le " save_as " clause à la fin de cela est important. Il s'assurera que le nom de fichier ne soit pas mutilé lorsqu'il est envoyé à votre navigateur. Éliminez-le pour observer ce qui se passe.

    self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
    

Bonne chance!

import os
import urllib

from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

class MainHandler(webapp.RequestHandler):
    def get(self):
        upload_url = blobstore.create_upload_url('/upload')
        self.response.out.write('<html><body>')
        self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
        self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form></body></html>""")

        for b in blobstore.BlobInfo.all():
            self.response.out.write('<li><a href="/serve/%s' % str(b.key()) + '">' + str(b.filename) + '</a>')

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]
        self.redirect('/')

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, blob_key):
        blob_key = str(urllib.unquote(blob_key))
        if not blobstore.get(blob_key):
            self.error(404)
        else:
            self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)

def main():
    application = webapp.WSGIApplication(
          [('/', MainHandler),
           ('/upload', UploadHandler),
           ('/serve/([^/]+)?', ServeHandler),
          ], debug=True)
    run_wsgi_app(application)

if __name__ == '__main__':
  main()

Autres conseils

En fait, cette question trouve une réponse dans la documentation de l'application Egnine. Voir un exemple sur le Téléchargement d'images d'utilisateur .

Code HTML à l'intérieur de < form > < / form >:

<input type="file" name="img"/>

Code Python:

class Guestbook(webapp.RequestHandler):
  def post(self):
    greeting = Greeting()
    if users.get_current_user():
      greeting.author = users.get_current_user()
    greeting.content = self.request.get("content")
    avatar = self.request.get("img")
    greeting.avatar = db.Blob(avatar)
    greeting.put()
    self.redirect('/')

Il existe un fil à ce sujet dans les groupes Google:

"> Téléchargement de fichiers

Avec beaucoup de code utile, cette discussion m'a beaucoup aidé dans le téléchargement de fichiers.

Google a publié un service permettant de stocker des fichiers volumineux. Consultez la documentation de l'API blobstore . Si vos fichiers sont & Gt; 1 Mo, vous devriez l'utiliser.

Je l'essaie aujourd'hui, il fonctionne comme suit:

ma version du sdk est la 1.3.x

page html:

<form enctype="multipart/form-data" action="/upload" method="post" > 
<input type="file" name="myfile" /> 
<input type="submit" /> 
</form> 

Code du serveur:

file_contents = self.request.POST.get('myfile').file.read() 

Si votre problème persiste, vérifiez que vous utilisez enctype dans la balise de formulaire

Non:

<form encoding="multipart/form-data" action="/upload">

Oui:

<form enctype="multipart/form-data" action="/upload">

Vous ne pouvez pas stocker de fichiers car il n’existe pas de système de fichiers traditionnel. Vous ne pouvez les stocker que dans leur propre stock de données (dans un champ défini comme BlobProperty )

Il y a un exemple dans le lien précédent:

class MyModel(db.Model):
  blob = db.BlobProperty()

obj = MyModel()
obj.blob = db.Blob( file_contents )

Personnellement, le tutoriel décrit ici utile lors de l'exécution de Java avec GAE. Pour une raison quelconque, lorsque j'ai essayé de télécharger un fichier à l'aide de

<form action="/testservelet" method="get" enctype="multipart/form-data">
    <div>
        Myfile:<input type="file" name="file" size="50"/>
    </div>

    <div>
        <input type="submit" value="Upload file">
    </div>
</form>

J'ai constaté que ma classe HttpServlet, pour une raison quelconque, n'accepterait pas le formulaire avec l'attribut 'enctype'. Le supprimer fonctionne, cependant, cela signifie que je ne peux télécharger aucun fichier.

Aucun fichier à plat n'est stocké dans Google App Engine. Tout doit être placé dans le Datastore , un peu comme une base de données relationnelle, mais pas tout à fait.

Vous pouvez stocker les fichiers sous le format TextProperty ou < a href = "http://code.google.com/appengine/docs/datastore/typesandpropertyclasses.html#BlobProperty" rel = "nofollow noreferrer"> Attributs BlobProperty .

Les entrées du stock de données ont une limite de 1 Mo, ce qui peut poser problème ou non.

J'ai observé un comportement étrange lors du téléchargement de fichiers sur App Engine. Lorsque vous soumettez le formulaire suivant:

<form method="post" action="/upload" enctype="multipart/form-data">
    <input type="file" name="img" />
    ...
</form>

Ensuite, vous extrayez le img de la requête comme suit:

img_contents = self.request.get('img')

La variable img_contents est un str() dans Google Chrome, mais elle est unicode dans Firefox. Et comme vous le faites maintenant, le constructeur db.Blob() prend une chaîne et génère une erreur si vous transmettez une chaîne unicode.

Quelqu'un sait-il comment résoudre ce problème?

De plus, ce que je trouve absolument étrange, c’est que lorsque je copie et colle l’application Guestbook (avec avatars), cela fonctionne parfaitement. Je fais tout exactement de la même manière dans mon code, mais ça ne marchera pas. Je suis sur le point de me tirer les cheveux.

Il existe un moyen d'utiliser le système de fichiers à plat (du point de vue de l'utilisation)

Il existe un projet de système de fichiers virtuel Google App Engine . qui est implémenté avec l’aide des API datastore et memcache pour émuler un système de fichiers ordinaire. En utilisant cette bibliothèque, vous pouvez utiliser dans votre projet un accès au système de fichiers similaire (en lecture et en écriture) .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top