Blobstore APIを使用してDropboxサービスを実装する(パート1)

Blobstore api -App Engineプラットフォームの最近の補充により、現在最大2Gb( オリジナルでは-50Mb、約Translator )の大きなファイルをダウンロードして共有できます。 また、APIを使用するのが最も難しいものの1つです。 短い一連のメモでは、Blobstore APIを使用してApp Engineに基づいた「ドロップボックス」サービスを実装する方法を示します。 まず、ファイルをダウンロードし、それらに関する情報をデータストアに保存し、ダウンロード用にユーザーに提供するために必要な基本事項を検討します。



アップロードフォームから始めましょう。 この手順は非常に明白です。標準のHTMLフォームを作成します。必要なことは、blobstore.create_upload_urlメソッドを呼び出して目的のハンドラーでURLを渡すことにより、フォームのアクションのURLを生成することだけです。 以下にコードを示します。

class FileUploadFormHandler(BaseHandler): @util.login_required def get(self): self.render_template("upload.html", { 'form_url': blobstore.create_upload_url('/upload'), 'logout_url': users.create_logout_url('/'), })
      
      





すべてが標準ですが、まだ注目に値します-便宜上、ユーザーがログインする必要がある(およびログインフォームにリダイレクトする)google.appengine.ext.webapp.utilパッケージのlogin_requiredデコレーターを使用します。 そして、これがテンプレートです:

 <html> <head> <title> </title> </head> <body> <p style="float: right"><a href="{{logout_url}}">Log Out</a></p> <h1>Upload a file to App Engine File Hangar</h1> <form method="POST" action="{{form_url}}" enctype="multipart/form-data"> <input type="file" name="file" /><br /> <input type="submit" value="Upload" /> </form> </body> </html>
      
      





formタグの属性に注意してください。methodは「POST」で、enctypeは「multipart / form-data」である必要があります。そうでない場合、ダウンロードは機能しません!



次に、ブートハンドラを作成します。 ダウンロードしたファイルに関する情報を保存するためのモデルの説明から始めましょう。 ここにあります:

 class FileInfo(db.Model): blob = blobstore.BlobReferenceProperty(required=True) uploaded_by = db.UserProperty(required=True) uploaded_at = db.DateTimeProperty(required=True, auto_now_add=True)
      
      





タイプがblobstore.BlobReferencePropertyの「blob」フィールドを除き、かなり標準的なモデルです。 BlobReferencePropertyはReferencePropertyに似ていますが、唯一の違いは別のモデルではなくBlobを参照することです。 要求に応じて、 BlobInfoオブジェクトが返されます。



ダウンロードプロセスに直接関与するコード:

 class FileUploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): blob_info = self.get_uploads()[0] if not users.get_current_user(): blob_info.delete() self.redirect(users.create_login_url("/")) return file_info = FileInfo(blob=blob_info.key(), uploaded_by=users.get_current_user()) db.put(file_info) self.redirect("/file/%d" % (file_info.key().id(),))
      
      





手順を見ていきましょう。 まず、ハンドラーは通常のwebapp.RequestHandlerではなくBlobstoreUploadHandlerクラスを継承します。 BlobstoreUploadHandlerは、ヘルパーメソッドself.get_uploads()を定義します。このメソッドは、ダウンロードされたファイルごとに1つのBlobInfoオブジェクトのリストを返します。



post()メソッドでは、self.get_uploads()を呼び出して最初の要素を取得します。 Blobstore APIは現在、1つのフォームでの複数のファイルアップロードをサポートしていないため、常に1つの要素のみが返され、単純にそれを抽出します( すでにサポートされています。 その後、何らかの形でフォームを送信する不正ユーザーから身を守ります。 ここでlogin_requiredデコレータを使用することはできません。ダウンロードの試行が許可されなかった場合、ファイルを削除する必要があるためです。 最後に、ダウンロードしたファイルのエントリをデータストアに作成し、新しく追加されたファイルに関する情報を使用してユーザーをワーカーにリダイレクトします。



次のステップでは、ダウンロードしたファイルに関する情報を受信して​​表示するハンドラーを実装します。 ここでは複雑なことはありません:

 class FileInfoHandler(BaseHandler): def get(self, file_id): file_info = FileInfo.get_by_id(long(file_id)) if not file_info: self.error(404) return self.render_template("info.html", { 'file_info': file_info, 'logout_url': users.create_logout_url('/'), })
      
      





表示するテンプレート:

 <html> <head> <title>  </title> </head> <body> <p style="float: right"><a href="{{logout_url}}">Log Out</a></p> <h1>  </h1> <table> <tr><th> </th><td>{{file_info.blob.filename}}</td></tr> <tr><th></th><td>{{file_info.blob.size}} bytes</td></tr> <tr><th> </th><td>{{file_info.uploaded_at}}</td></tr> <tr><th> </th><td>{{file_info.uploaded_by}}</td></tr> <tr><th>Content Type</th><td>{{file_info.blob.content_type}}</td></tr> </table> <p><a href="/file/{{file_info.key.id}}/download">  </a></p> </body> </html>
      
      





最後に、ファイルをユーザーに直接提供するハンドラー:

 class FileDownloadHandler(blobstore_handlers.BlobstoreDownloadHandler): def get(self, file_id): file_info = FileInfo.get_by_id(long(file_id)) if not file_info or not file_info.blob: self.error(404) return self.send_blob(file_info.blob, save_as=True)
      
      





ここでは、キーによってFileInfoエントリを要求し、存在し、blobが含まれている場合、親クラスBlobstoreDownloadHandlerによって提供されるsend_blobヘルパーメソッドを呼び出します。 Trueに設定された追加の引数 'save_as'を渡すと、ブラウザーでの表示ではなく、ダウンロードのためにファイルが送信されることが保証されます。 特定のファイル名を示すために、Trueの代わりにファイル名を指定することもできます。デフォルトでは、これはファイルのダウンロードに使用された名前です。



この記事では、Blobstoreで何ができるかを表面的に説明しているだけです。より完全な全体像については、ドキュメントから多くを学ぶことができます。 これらは必要な基本ですが、次のパートでは、ユーザーエクスペリエンスを向上させるために、JavaScriptまたはFlashでダウンロードウィジェットのサポートを追加します。

すべてを実際にテストしたい人のために、デモアプリケーションのソースコードはこちらから入手できます



All Articles