Pergunta

Estou planejando criar um aplicativo da web que permita aos usuários fazer downgrade de seus arquivos de projeto do Visual Studio.No entanto, parece que o Google App Engine aceita upload de arquivos e armazenamento de arquivos simples no servidor do Google por meio de db.TextProperty e db.BlobProperty.

Ficarei feliz que alguém possa fornecer um exemplo de código (tanto do lado do cliente quanto do servidor) sobre como isso pode ser feito.

Foi útil?

Solução

Aqui está um arquivo completo, trabalhando. Puxei o original da página do Google e modificado para torná-la mundo um pouco mais real.

Algumas coisas a notar:

  1. Este código usa o blobstore API
  2. O objectivo desta linha no classe ServeHandler é "consertar" o chave para que ele se livrar de qualquer nome calandrar que pode ter ocorrido em o navegador (eu não observaram em Chrome)

    blob_key = str(urllib.unquote(blob_key))
    
  3. O "save_as" cláusula no final isso é importante. Ele vai se certificar de que o nome do arquivo não fica mutilado quando ele é enviado para o seu browser. Se livrar dele para observar o que acontece.

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

Boa sorte!

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

Outras dicas

Na verdade, esta pergunta for respondida na documentação do App Egnine. Veja um exemplo na upload de Usuários Imagens .

código HTML, dentro de

:

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

código 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('/')

Há um fio em Grupos do Google sobre isso:

Carregamento de arquivos

Com um monte de código útil, essa discussão me ajudou muito no upload de arquivos.

O Google lançou um serviço para armazenar arquivos grandes. Ter um olhar para blobstore API documentação . Se os arquivos estiverem> 1MB, você deve usá-lo.

I tentar hoje, Ele funciona da seguinte forma:

minha versão SDK é 1.3.x

html página:

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

Código Servidor:

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

Se o seu ainda ter um problema, verifique você está usando enctype na tag form

Não:

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

Sim:

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

Você não pode armazenar arquivos como não há um sistema de arquivos tradicional. Você só pode armazená-los em seu próprio DataStore (em um campo definido como um BlobProperty )

Há um exemplo no link anterior:

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

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

Pessoalmente, achei o tutorial descrito aqui útil quando se usa o tempo de execução Java com GAE. Por alguma razão, quando eu tentei fazer upload de um arquivo usando

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

Descobri que minha classe HttpServlet por algum motivo não aceitaria o formulário com o atributo 'enctype'. Removendo funciona, no entanto, isso significa que eu não posso fazer upload de qualquer arquivo.

Não há nenhum arquivo simples armazenamento no Google App Engine. Tudo tem que ir para a Datastore que é um pouco como um banco de dados relacional, mas não completamente.

Você pode armazenar os arquivos como TextProperty ou < a href = "http://code.google.com/appengine/docs/datastore/typesandpropertyclasses.html#BlobProperty" rel = "nofollow"> noreferrer atributos BlobProperty .

Há um limite de 1MB em entradas DataStore que pode ou não pode ser um problema.

Tenho observado um comportamento estranho ao fazer upload de arquivos no Google App Engine. Quando você enviar o formulário a seguir:

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

E então você extrair o img do pedido como este:

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

A variável img_contents é um str() no Google Chrome, mas é unicode no Firefox. E como você agora, o construtor db.Blob() recebe uma string e irá lançar um erro se você passar uma cadeia unicode.

Alguém sabe como isso pode ser corrigido?

Além disso, o que eu acho absolutamente estranho é que quando eu copiar e colar o aplicativo Livro de visitas (com avatares), ele funciona perfeitamente. Eu faço tudo exatamente da mesma maneira no meu código, mas ele simplesmente não vai funcionar. Estou muito perto de puxar meu cabelo para fora.

Existe uma maneira de usar o sistema de arquivo simples (Pelo menos na perspectiva de uso)

Não é este Google App Engine projecto sistema de arquivos virtual . que é implementado com a ajuda de APIs de armazenamento de dados e memcache para emular um sistema de arquivos comum. Usando esta biblioteca você pode usar no seu projeto um acesso sistema de arquivos semelhante (ler e escrever) .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top