it-swarm-eu.dev

Laden Sie Dateien in Google App Engine hoch

Ich plane, eine Web-App zu erstellen, mit der Benutzer ihre Visual Studio-Projektdateien downgraden können. Offenbar akzeptiert Google App Engine jedoch das Hochladen von Dateien und das Speichern von Einfachdateien auf dem Google-Server über db.TextProperty und db.BlobProperty.

Ich bin froh, dass jeder ein Codebeispiel (sowohl auf Client- als auch auf Serverseite) zur Verfügung stellen kann, wie dies getan werden kann.

77
Graviton

Hier ist eine vollständige Arbeitsdatei. Ich habe das Original von der Google-Website genommen und es geändert, um es etwas realer zu gestalten.

Ein paar Dinge zu beachten:

  1. Dieser Code verwendet die BlobStore-API
  2. Der Zweck dieser Zeile in der ServeHandler-Klasse besteht darin, den Schlüssel so zu "korrigieren", dass etwaige Namensverfälschungen im Browser beseitigt werden (in Chrome habe ich keine festgestellt).

    blob_key = str(urllib.unquote(blob_key))
    
  3. Die "save_as" -Klausel am Ende ist wichtig. Es wird sichergestellt, dass der Dateiname nicht beschädigt wird, wenn er an Ihren Browser gesendet wird. Werde es los, um zu beobachten, was passiert.

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

Viel Glück!

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 __== '__main__':
  main()
42
010110110101

Tatsächlich wird diese Frage in der App Egnine-Dokumentation beantwortet. Ein Beispiel finden Sie unter Hochladen von Benutzerbildern .

HTML-Code in <form> </ form>:

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

Python-Code:

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 ('/')
49
sastanin

In Google Groups gibt es einen Thread dazu:

Hochladen von Dateien

Mit vielen nützlichen Codes hat mir diese Diskussion beim Hochladen von Dateien sehr geholfen.

10

Ich versuche es heute, es funktioniert wie folgt:

meine sdk version ist 1.3.x

hTML Seite:

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

Server Code:

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

Google hat einen Dienst zum Speichern großer Dateien veröffentlicht. Schauen Sie sich Blobstore-API-Dokumentation an. Wenn Ihre Dateien größer als 1 MB sind, sollten Sie sie verwenden.

6
jbochi

Wenn Sie immer noch ein Problem haben, überprüfen Sie, ob Sie enctype im Formular-Tag verwenden

Nein:

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

Ja:

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

Sie können keine Dateien speichern, da es kein traditionelles Dateisystem gibt. Sie können sie nur in ihrem eigenen DataStore (in einem als BlobProperty definierten Feld) speichern.

Es gibt ein Beispiel im vorherigen Link:

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

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

Persönlich fand ich das beschriebene Tutorial hier nützlich bei der Verwendung der Java Laufzeit mit GAE. Aus irgendeinem Grund, als ich versuchte, eine Datei mit hochzuladen

<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>

Ich habe festgestellt, dass meine HttpServlet-Klasse aus irgendeinem Grund das Formular mit dem Attribut 'enctype' nicht akzeptiert. Das Entfernen funktioniert jedoch, dh ich kann keine Dateien hochladen.

1
Vijay Sharma

Es gibt eine Möglichkeit, das Flat-File-System zu verwenden (zumindest in der Nutzungsperspektive)

Es gibt dieses Google App Engine Virtual FileSystem-Projekt . Dies wird mithilfe von Datenspeicher- und Memcache-APIs implementiert, um ein gewöhnliches Dateisystem zu emulieren. Mit dieser Bibliothek können Sie in Ihrem Projekt einen ähnlichen Dateisystemzugriff (Lesen und Schreiben) verwenden .

0
vivek_jonam

In Google App Engine wird keine Flat-Datei gespeichert. Alles muss in den Datastore gehen, der ein bisschen wie eine relationale Datenbank ist, aber nicht ganz.

Sie könnten die Dateien als TextProperty oder BlobProperty Attribute speichern.

Es gibt eine 1-MB-Beschränkung für DataStore-Einträge, die möglicherweise ein Problem darstellen oder nicht.

0
Dave Webb

Beim Hochladen von Dateien auf App Engine ist ein merkwürdiges Verhalten aufgetreten. Wenn Sie das folgende Formular einreichen:

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

Und dann extrahieren Sie das img aus der Anfrage wie folgt:

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

Die Variable img_contents Ist in Google Chrome ein str(), in Firefox jedoch ein Unicode. Und wie Sie jetzt, nimmt der Konstruktor db.Blob() eine Zeichenfolge und wird einen Fehler auslösen, wenn Sie eine Unicode-Zeichenfolge übergeben.

Weiß jemand, wie das behoben werden kann?

Absolut seltsam finde ich auch, dass das Kopieren und Einfügen der Gästebuch-Anwendung (mit Avataren) perfekt funktioniert. Ich mache alles genauso in meinem Code, aber es wird einfach nicht funktionieren. Ich bin kurz davor, mir die Haare auszuziehen.

0
Honza Pokorny