2

電子メールを解析して添付ファイルを見つけ、それらを db.BlobProperties としてデータストアに保存するコードがいくつかあります (後で Blobstore に変更する可能性があります)。問題は、UTF8 でエンコードされたテキスト ファイルを送信すると、エラーが発生することです。

コードは基本的にファイルを保存し、文字列に変換されてから親メール エンティティに格納されるキーを返します。ご覧のとおり、ファイルをデコードしてから blob として保存します。多くの添付ファイルを送信しましたが、このコードは Unicode でエンコードされたテキスト以外のすべてで機能します。これを行うより良い方法はありますか?Unicode テキストの添付ファイルを処理するにはどうすればよいですか?

コードスニピット

    my_file = []
    my_list = []
    if hasattr(mail_message, 'attachments'):
        file_name = ""
        file_blob = ""
        for filename, filecontents in mail_message.attachments:
            file_name = filename
            file_blob = filecontents.decode()
            my_file.append(file_name)
            my_list.append(str(store_file(self, file_name, file_blob)))

store_file

def store_file(self, file_name, file_blob):
    new_file = myblob(file_name = file_name, 
                      file_blob = file_blob)
    return new_file.put()

上記で使用file_blob = str(file_blob)してみましたが、役に立ちませんでした。それはコードを壊すだけで、ファイルは決して保存されません。

Unicode テキスト ファイルのログ 1

Property file_blob must be convertible to a Blob instance (Blob() argument should be str instance, not unicode)
Traceback (most recent call last):
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/webapp/mail_handlers.py", line 65, in post
    self.receive(mail.InboundEmailMessage(self.request.body))
  File "/base/data/home/apps/s~ae-baseapp/1.359073377819595139/controllers/InboundHandler.py", line 51, in receive
    file_list.append(str(store_file(self, file_name, file_blob)))
  File "/base/data/home/apps/s~ae-baseapp/1.359073377819595139/models/MyModel.py", line 63, in store_file
    file_blob = file_blob)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 974, in __init__
    prop.__set__(self, value)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 614, in __set__
    value = self.validate(value)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2780, in validate
    (self.name, self.data_type.__name__, err))
BadValueError: Property file_blob must be convertible to a Blob instance (Blob() argument should be str instance, not unicode)

filecontents.decode() を削除し、filecontents だけに置き換えたログ 2。

Property file_blob must be convertible to a Blob instance (Blob() argument should be str instance, not EncodedPayload)
Traceback (most recent call last):
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/webapp/mail_handlers.py", line 65, in post
    self.receive(mail.InboundEmailMessage(self.request.body))
  File "/base/data/home/apps/s~ae-baseapp/1.359097282640216691/controllers/InboundHandler.py", line 57, in receive
    file_list.append(str(store_file(self, file_name, file_blob)))
  File "/base/data/home/apps/s~ae-baseapp/1.359097282640216691/models/MyModel.py", line 64, in store_file
    file_blob = file_blob)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 974, in __init__
    prop.__set__(self, value)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 614, in __set__
    value = self.validate(value)
  File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2780, in validate
    (self.name, self.data_type.__name__, err))
BadValueError: Property file_blob must be convertible to a Blob instance (Blob() argument should be str instance, not EncodedPayload)
4

2 に答える 2

2

このコードが役立つかどうかを確認します。

===========================

   my_file = []
    my_list = []
    if hasattr(mail_message, 'attachments'):
        file_name = ""
        for filename, filecontents in mail_message.attachments:
            file_name = filename
            file_blob = filecontents.payload
            file_blob = file_blob.decode(filecontents.encoding)
            my_file.append(file_name)
            my_list.append(str(store_file(self, file_name, file_blob)))
于 2012-10-01T06:38:23.637 に答える
2

添付ペイロードは、EncodedPayloadクラスのインスタンスです。添付ファイルには、エンコーディングとオプションの文字セットがあります。前者は、base64 などの転送エンコーディングを指します。後者は、UTF-8 などの文字エンコーディングに変換されます (文字セットは、ここでは少し時代遅れで誤解を招く用語です)。このEncodedPayload.decode()メソッドは、転送エンコーディングとテキスト エンコーディングの両方をデコードします。お気づきのように、ユーザーがメッセージに添付した元のバイトを取得したいだけの場合、これはあまり役に立ちません。

ここで採用できるアプローチはいくつかありますが、転送エンコーディングをデコードするための EncodedPayload のロジックを複製することをお勧めします。これは次のようになります。

if filecontents.encoding and filecontents.encoding.lower() != '7bit':
  try:
    payload = filecontents.payload.decode(filecontents.encoding)
  except LookupError:
    raise UnknownEncodingError('Unknown decoding %s.' % filecontents.encoding)
  except (Exception, Error), e:
    raise PayloadEncodingError('Could not decode payload: %s' % e)
else:
  payload = filecontents.payload

添付ファイルテキストの場合は、保存時に文字エンコーディングを含める必要があることに注意してください。そうしないと、ユーザーに送り返すときに解釈する方法がありません。元のテキストは、任意の文字エンコーディングを使用してエンコードされている可能性があります。 .

同様に、可能であれば添付ファイルの MIME タイプも保存する必要がありますが、これは API のどこにも公開されていないようです。IncomingMessage クラスの使用をまったく避け、代わりに Python の MIME メッセージ モジュールを使用して POST 要求の本文をデコードすることを検討することをお勧めします。

于 2012-05-23T01:19:03.847 に答える