Google App Engine アプリケーションで titan-files を使用して、データ ストアとブロブ ストア ストレージにファイル システムのようなレイヤーを提供しています。Google App Engine アプリケーションに POST リクエストを送信してデータをブロブ ストアに保存する Google Apps Script があります。JSON データを (文字列として) 送信する場合は正常に機能しますが、画像などのバイナリ データを送信する場合は機能しません。
最終的に、base64 でエンコードされたデータを文字列として送信し、ブロブ ストアに保存しようとしました。ブロブ ストアからデータを取得し、base64 でデコードして元の画像を取得できると考えました。しかし、うまくいかないようです。
Google Apps Script からデータを送信するために使用しているコードは次のとおりです。
function pushFileToFilePath(file, destinationFilePath) {
var payload =
{
"content" : Utilities.base64Encode(file.getAs("image/jpeg").getBytes())
};
var options =
{
"method" : "post",
"payload" : payload
};
var response = UrlFetchApp.fetch("https://myappname.appspot.com/_titan/file?path=" + destinationFilePath, options);
if (response.getResponseCode() == 201)
{
return true;
}
return false;
}
要求が送信された後、データはブロブ ストアで利用可能になり、そのサイズは、ファイルを base64 でエンコードした結果から予想されるサイズと一致しています。ただし、Google App Engine ダッシュボードを使用してブロブ ストアからファイルをダウンロードし、base64 でデコードすると、
openssl -d -in base_64_encoded_file.txt -out image.jpg
ゼロバイトの image.jpg ファイルを取得します。
また、ペイロード オブジェクトをセットアップする他の方法も試しました。たとえば、次を使用します。
var payload =
{
"content" : file.getAs("image/jpeg").getBytes()
};
文字列 "[Ljava.lang.Object" を含む 18 バイトのファイルをブロブ ストアに作成します。使用:
var payload =
{
"content" : file.getAs("image/jpeg")
};
Google App Engine のログに次の例外が記録されます。
Bad request:
Traceback (most recent call last):
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/handlers.py", line 103, in post
content, blob=blob, mime_type=mime_type, meta=meta, **method_kwargs)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/files.py", line 408, in Write
content, blob = self._MaybeWriteToBlobstore(content, blob)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/files.py", line 341, in _MaybeWriteToBlobstore
blob = utils.WriteToBlobstore(content, old_blobinfo=old_blobinfo)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/common/utils.py", line 277, in WriteToBlobstore
content_file = cStringIO.StringIO(content)
TypeError: expected read buffer, instance found
BytesIO を使用してコンテンツをストリーミングしようとしましたが、他の例外が発生しました。
画像 (またはより一般的にはバイナリ データ) を titan ファイルに POST する方法について何か考えはありますか?
ありがとうございました!
アップデート
これから「コンテンツ」データを取得する方法を変更して、問題を修正しました。
content = self.request.str_POST.get('content')
これに:
content = self.request.get('content')
そして、Google Apps Script で次のコードを使用してデータを送信します。
var payload =
{
"content" : file.getAs("image/jpeg")
};
つまり、「コンテンツ」を Blob インスタンスに設定するだけです。
そもそもなぜこれを試さなかったのかわかりません:)とにかく、titan-fileの変更はハックであり、永続的な解決策ではないので、両方を処理するしっかりしたパッチを考え出そうとします.バイナリ データと非バイナリ データを作成し、プロジェクトに提出します。
ありがとうございました!