编程语言
首页 > 编程语言> > 在Unicode文本文件中接收App Engine中的电子邮件附件Python错误

在Unicode文本文件中接收App Engine中的电子邮件附件Python错误

作者:互联网

我有一些代码来解析电子邮件并找到附件,然后将它们作为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)

记录2删除filecontents.decode()并将其替换为filecontents.

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)

解决方法:

附件有效负载是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

请注意,如果附件是文本,则需要在存储时包含字符编码,或者在将其发送回用户时无法解释它 – 原始文本可能已使用任何字符编码进行编码.

同样,如果可以,您还应该保存附件的mimetype,但这似乎不会暴露在API中的任何位置.您可能想要考虑完全避免使用IncomingMessage类,而是使用Python的mime消息模块解码POST请求的主体.

标签:email-attachments,python,python-2-7,google-app-engine,email
来源: https://codeday.me/bug/20191009/1876003.html