Python 作为化身写入数据存储并将图像附加到数据存储:可能吗?
是否有人在收到的电子邮件中使用附件?我在想,用户不用上传图像,而是可以将其作为附件发送,我可以用它上传到数据存储 文档已被删除,但我找不到任何关于接收附件的文档: 附件 邮件的文件附件,作为两个值元组的列表,每个附件一个元组 每个元组包含一个文件名作为第一个元素,文件内容作为第二个元素 附件文件必须是允许的文件类型之一,并且文件名必须以与该类型对应的扩展名结尾。有关允许的类型和文件扩展名的列表,请参阅概述:附件 我认为这也是关于发送电子邮件 我有以下代码将图像保存到数据存储:Python 作为化身写入数据存储并将图像附加到数据存储:可能吗?,python,google-app-engine,email,google-cloud-datastore,Python,Google App Engine,Email,Google Cloud Datastore,是否有人在收到的电子邮件中使用附件?我在想,用户不用上传图像,而是可以将其作为附件发送,我可以用它上传到数据存储 文档已被删除,但我找不到任何关于接收附件的文档: 附件 邮件的文件附件,作为两个值元组的列表,每个附件一个元组 每个元组包含一个文件名作为第一个元素,文件内容作为第二个元素 附件文件必须是允许的文件类型之一,并且文件名必须以与该类型对应的扩展名结尾。有关允许的类型和文件扩展名的列表,请参阅概述:附件 我认为这也是关于发送电子邮件 我有以下代码将图像保存到数据存储: class Ava
class AvatarSave(webapp.RequestHandler):
def post(self):
q = User.all()
q.filter("userEmail =", emailAddress)
qTable = q.fetch(10)
if qTable:
for row in qTable:
avatar = images.resize(self.request.get("img"), 50, 50)
row.avatar = db.Blob(avatar)
db.put(qTable)
else:
self.response.out.write("user not found")
self.redirect('/')
直观地看,似乎message.attachment
而不是“img”
会起作用
avatar = images.resize(self.request.get(message.attachment), 50, 50)
你觉得怎么样?谢谢
更新2(回应尼克·约翰逊评论的新代码)
更新1问题已解决: 为了记录在案,对于任何有相同问题的人,请注意,是
附件
而不是附件
:
message.attachment
给出属性错误
AttributeError: 'InboundEmailMessage' object has no attribute 'attachment'
对象message.attachment
如下所示:
[('portrait.png', <EncodedPayload payload=#8461006914571150170 encoding=base64>)]
for row in qTable:
avatar = images.resize(self.request.get("img"), 50, 50)
row.avatar = db.Blob(avatar)
db.put(qTable)
self.redirect('/')
else:
logging.info("else user not found")
self.redirect('/user-not-found')
我发布的原始代码
avatar = images.resize(goodDecode(message.attachments[1]), 50, 50)
这显然是行不通的
再次感谢jesmith
和Robert Kluin
的回答
更新0(关于jesmith的回答) 在我的例子中,我从用户上传的表单中获取图像
“img”
,并将其写入数据存储,如下所示:
[('portrait.png', <EncodedPayload payload=#8461006914571150170 encoding=base64>)]
for row in qTable:
avatar = images.resize(self.request.get("img"), 50, 50)
row.avatar = db.Blob(avatar)
db.put(qTable)
self.redirect('/')
else:
logging.info("else user not found")
self.redirect('/user-not-found')
在您的代码中,这与本节相对应,我相信:
try:
if hasattr(message, "attachment"):
for a in message.attachments:
msg.attachmentNames.append(a[0])
msg.attachmentContents.append(append(db.Blob(goodDecode(a[1])))
msg.put()
except:
logging.exception("exception decoding attachments in email from %s" % message.sender)
假设,在我的情况下,只有1个附件;如何提取附件的数据部分
是否是消息。附件[1]
avatar = images.resize(message.attachment[1], 50, 50)
message.attachment[1]
数据是附件的一部分吗
谢谢 查看电子邮件文档中的部分,它解释了附件属性
InboundEmailMessage对象
包括访问其他文件的属性
消息字段:
- 附件是文件附件的列表,可能为空。每个 列表中的值是两个元组 元素:文件名和文件名 内容
for file_name, data in message.attachments:
# add some tests to check that the
# file-type is correct and that the
# data-size is "OK".
avatar = db.Blob(data)
当用户附加多个图像时,您需要决定如何处理该情况。这将只使用最后一个附件。查看电子邮件文档中的部分,它解释了附件属性
InboundEmailMessage对象
包括访问其他文件的属性
消息字段:
- 附件是文件附件的列表,可能为空。每个 列表中的值是两个元组 元素:文件名和文件名 内容
for file_name, data in message.attachments:
# add some tests to check that the
# file-type is correct and that the
# data-size is "OK".
avatar = db.Blob(data)
当用户附加多个图像时,您需要决定如何处理该情况。这将只使用最后一个附件。这是我使用的传入邮件处理程序的一个片段:
bodies = message.bodies(content_type='text/html')
allBodies = u"";
for body in bodies:
allBodies = allBodies + u"\n" + unicode(goodDecode(body[1]), errors="ignore")
if not allBodies:
bodies = message.bodies(content_type='text/plain')
for body in bodies:
allBodies = allBodies + u"\n" + unicode(goodDecode(body[1]), errors="ignore")
msg = EmailMessageModel()
...fill in various stuff...
msg.sender = message.sender
msg.date = datetime.datetime.now()
msg.message = allBodies
# Calling put() before dealing with attachments because it seems like that could throw various exceptions
msg.put()
event.email = True
event.put()
event.project.email = True
event.project.put()
# attachments is a list of element pairs containing file names and contents.
try:
if hasattr(message, 'attachments'):
for a in message.attachments:
msg.attachmentNames.append(a[0])
msg.attachmentContents.append(db.Blob(goodDecode(a[1])))
msg.put()
except:
logging.exception("Exception decoding attachments in email from %s" % message.sender)
请注意,goodDecode是我编写的一个函数,因为底层GAE decode中有一个bug(它将所有内容都小写,其中包含base64编码的文本):
这可能不再需要了,因为我很确定他们已经修复了这个bug
在我的例子中,我正在将附件填充到数据库中:
class EmailMessageModel(db.Model):
....various stuff...
sender = db.StringProperty()
date = db.DateTimeProperty()
message = db.TextProperty()
attachmentNames = db.StringListProperty()
attachmentContents = db.ListProperty(db.Blob)
当我想显示此电子邮件时,我使用以下命令:
<h2>{{ e.sender }} {{ e.date|date:"M j, Y f A " }} GMT</h2>
<p>From: {{ e.sender }}<br/>Date: {{ e.date|date:"M j, Y f A" }} GMT ({{ e.date|timesince }} ago)<br/>Subject: {{ e.subject }}</p>
{% if e.attachmentNames %}
<p>Attachments:
{% for a in e.attachmentNames %}
<a href="/admin/attachment?email={{ e.key }}&index={{ forloop.counter0 }}" target="_blank">{{ a }}</a>
{% endfor %}
</p>
{% endif %}
<div style='background-color: white'>{{ e.message }}</div>
(因此,基本上,我让浏览器决定如何处理附件。)
希望这有帮助 这是我使用的传入邮件处理程序的一个片段:
bodies = message.bodies(content_type='text/html')
allBodies = u"";
for body in bodies:
allBodies = allBodies + u"\n" + unicode(goodDecode(body[1]), errors="ignore")
if not allBodies:
bodies = message.bodies(content_type='text/plain')
for body in bodies:
allBodies = allBodies + u"\n" + unicode(goodDecode(body[1]), errors="ignore")
msg = EmailMessageModel()
...fill in various stuff...
msg.sender = message.sender
msg.date = datetime.datetime.now()
msg.message = allBodies
# Calling put() before dealing with attachments because it seems like that could throw various exceptions
msg.put()
event.email = True
event.put()
event.project.email = True
event.project.put()
# attachments is a list of element pairs containing file names and contents.
try:
if hasattr(message, 'attachments'):
for a in message.attachments:
msg.attachmentNames.append(a[0])
msg.attachmentContents.append(db.Blob(goodDecode(a[1])))
msg.put()
except:
logging.exception("Exception decoding attachments in email from %s" % message.sender)
请注意,goodDecode是我编写的一个函数,因为底层GAE decode中有一个bug(它将所有内容都小写,其中包含base64编码的文本):
这可能不再需要了,因为我很确定他们已经修复了这个bug
在我的例子中,我正在将附件填充到数据库中:
class EmailMessageModel(db.Model):
....various stuff...
sender = db.StringProperty()
date = db.DateTimeProperty()
message = db.TextProperty()
attachmentNames = db.StringListProperty()
attachmentContents = db.ListProperty(db.Blob)
当我想显示此电子邮件时,我使用以下命令:
<h2>{{ e.sender }} {{ e.date|date:"M j, Y f A " }} GMT</h2>
<p>From: {{ e.sender }}<br/>Date: {{ e.date|date:"M j, Y f A" }} GMT ({{ e.date|timesince }} ago)<br/>Subject: {{ e.subject }}</p>
{% if e.attachmentNames %}
<p>Attachments:
{% for a in e.attachmentNames %}
<a href="/admin/attachment?email={{ e.key }}&index={{ forloop.counter0 }}" target="_blank">{{ a }}</a>
{% endfor %}
</p>
{% endif %}
<div style='background-color: white'>{{ e.message }}</div>
(因此,基本上,我让浏览器决定如何处理附件。)
希望这有帮助 是的,针对您的后续行动: 是邮件吗?附件[1] 是的,但你需要解码。否则,您只会得到大量ASCII字符(在电子邮件中,附件总是编码为7位、短线、1975安全格式,如base64)
别忘了使用大量的try-catch逻辑,因为GAE中的邮件很容易抛出大量异常。是的,作为对后续操作的响应: 是邮件吗?附件[1] 是的,但你需要解码。否则,您只会得到大量ASCII字符(在电子邮件中,附件总是编码为7位、短线、1975安全格式,如base64)
不要忘记使用大量的try-catch逻辑,因为GAE中的邮件内容容易抛出大量异常。非常感谢您的回复。这很有帮助。我添加了一个更新,其中有一个问题是关于如何使您的代码适应我的情况。我感谢你的帮助。再次感谢。非常感谢您的回复。这很有帮助。我添加了一个更新,其中有一个问题是关于如何使您的代码适应我的情况。我感谢你的帮助。再次感谢。为什么不使用电子邮件作为用户实体的密钥名?您的模型允许复制用户,您可以获取其中10个,并使用虚拟形象更新所有用户(?!)-这似乎很奇怪。@尼克,谢谢您指出这一点。我删除了那个密码;因为我意识到用户只是在注册;我不需要注册新用户的电子邮件;保存到数据库中;然后再次拉它来更新化身。所以现在我在一个p里做了所有的事情