将数据存储作为化身写入和图像附件:有可能吗?

2024-05-16 22:31:41 发布

您现在位置:Python中文网/ 问答频道 /正文

有人在收到的电子邮件中处理附件吗?我在想,不用用户上传图片,他们可以把它作为附件发送,我可以用它上传到数据存储。在

文档有sending attachments,但我找不到任何有关接收附件的文档。This page says

attachments

The file attachments for the message, as a list of two-value tuples, one tuple for each attachment.

Each tuple contains a filename as the first element, and the file contents as the second element.

An attachment file must be one of the allowed file types, and the filename must end with an extension that corresponds with the type. For a list of allowed types and filename extensions, see Overview: Attachments.

我想这也是关于发送电子邮件的。在

我有以下代码将图像保存到数据存储:

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而不是{}会起作用。在

^{pr2}$

你觉得怎么样?谢谢。在


更新2(新代码作为对尼克·约翰逊评论的回应)

class Register(InboundMailHandler):
    def receive(self, message):
        senderEmail = message.sender
        emailTuple = parseaddr(senderEmail)
        emailUserName = emailTuple[0]
        emailAddress = emailTuple[1]
        newAvatar = db.Blob(images.resize(goodDecode(message.attachments[0][1]), 50, 50))        
        newUser = User(userEmail=emailAddress,
                       userName=emailUserName,
                       avatar=newAvatar)

        db.put(newUser)

更新1问题已解决:

为了记录在案,对于任何有相同问题的人,请注意attribute of messageattachments不是{}:

message.attachment

给出AttributeError

AttributeError: 'InboundEmailMessage' object has no attribute 'attachment'

对象message.attachment如下所示:

[('portrait.png', <EncodedPayload payload=#8461006914571150170 encoding=base64>)]

所以拉<EncodedPayload payload=#8461006914571150170 encoding=base64>部分的正确方法是

avatar = images.resize(goodDecode(message.attachments[0][1]), 50, 50)

我发布的原始代码

avatar = images.resize(goodDecode(message.attachments[1]), 50, 50)

这显然行不通。在

再次感谢jesmith和{}的回答。在


更新0(关于jesmith的答案)

在我的例子中,我从用户上传的表单中获取一个图像"img",并将其写入数据存储,如下所示:

       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)

假设在我的例子中,只有一个附件;如何提取附件的数据部分?在

message.attachment[1]?在

avatar = images.resize(message.attachment[1], 50, 50)

message.attachment[1]数据是附件的一部分吗?在

谢谢!在


Tags: ofthe数据selfmessagefordb附件
3条回答

是的,针对您的跟进:

Is it message.attachment[1] ?

是的,但你需要解码。否则,您只会得到一大块ASCII字符(在电子邮件中,附件总是编码成7位、短线、1975安全格式,例如base64)。在

avatar = images.resize(goodDecode(message.attachment[1]), 50, 50)

别忘了在它周围使用大量try-catch逻辑,因为GAE中的邮件容易抛出很多异常。在

这是我使用的传入邮件处理程序的片段:

   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编码的文本):

^{pr2}$

这可能不再有必要了,因为我确信他们已经修复了那个错误。在

在我的例子中,我将附件填充到数据库中:

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>

附件处理程序是:

class AttachmentHandler(webapp.RequestHandler):
  def get(self):
    email = EmailMessageModel.get(self.request.get('email'))
    index = self.request.get('index')
    if index:
      index = int(index)
      filename = email.attachmentNames[index]
      self.response.headers['Content-Type'] = str(mimetypes.guess_type(filename)[0]) or 'application/octet-stream'
      self.response.out.write(email.attachmentContents[index])

(所以,基本上,我是让浏览器知道如何处理附件。)

希望这有帮助!在

查看电子邮件文档中的Handling Incoming Email部分,它解释了attachments属性。在

The InboundEmailMessage object includes attributes to access other message fields:

  • attachments is a list of file attachments, possibly empty. Each value in the list is a tuple of two elements: the filename and the file contents.

所以你会想要这样的东西:

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)

当用户附加多个图像时,您需要决定如何处理这种情况。这将只使用最后一个附件。在

相关问题 更多 >