MailBox.py :  » Email » BoboMail » bobomail » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Email » BoboMail 
BoboMail » bobomail » MailBox.py
"""This module is responsible for the web-intercation of the mail stuff

"""
from lib.util import quotedtext,urlunquote
from mimeviewer import getMIMEPart,MessageViewer
from Message import Message
from string import lower

from bobomod import *

from main import list_template,mail_template,compose_template
from main import bounce_template,sent_template
from main import status_message,image_dir
from main import use_imap

import os; pathsplit = os.path.split

class MailBox(BoboMailModule):
  """MailBox class for BoboMail
  Probably the most important part
  """

  def __init__(self, parent_arg, MailboxClass):
    BoboMailModule.__init__(self, parent_arg)
    self.Mailbox = MailboxClass

  def getMailbox(self, auth):
    "return mailbox"
    mb = self.Mailbox()
    mb.open(auth)
    return mb
    
  def getSender(self, auth):
      "return valid From-header"
      sender = auth.user.id
      if "@" not in sender:
    sender = "%s@%s" % (sender, auth.user.domain)
      if auth.user.name: 
    sender = '"%s" <%s>' % (auth.user.name, sender)
      return sender

  def markmsg(self, auth, msg):
    "mark messages as new"
    newmsgs = auth.user.newmsgs
    msgid = msg.getheader("message-id")
    if msgid not in newmsgs:
      newmsgs.append(msgid)
      auth.user.newmsgs = newmsgs

  def unmarkmsg(self, auth, msg):
    "mark messages as read"
    newmsgs = auth.user.newmsgs
    msgid = msg.getheader("message-id")
    if msgid in newmsgs:
      newmsgs.remove(msgid)
      auth.user.newmsgs = newmsgs

  def List(self, REQUEST, qs=0, by="", lastBy="", message=0, folder="INBOX"):
    "Show mails"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msgs = mbox()
    newmsgs = auth.user.newmsgs
    for i in range(len(msgs)):
      msgid = msgs[i].getheader("message-id")
      if msgid not in newmsgs:
        msgs[i].isNew = 1
    auth.user.newmsgs = newmsgs
    if not by:
      sby = auth.user.sortby
      if sby: by, reversed = sby
      else: by, reversed = "Date", "reverse"
      lastBy = by
    else:
      if by == lastBy: lastBy, reversed = "", "reverse"
      else: lastBy, reversed = by, ""
    auth.user.sortby = (by, reversed)
    folders = mbox.folders()
    return self.genHTML(REQUEST, open(list_template),
              {"%(by)s": by, "%(reversed)s": reversed,
               "%(listsize)s": str(auth.user.maxlistsize)},
              mails=msgs, qs=qs, lastBy=lastBy,
              folders=folders, folder=folder,
              message=status_message[message],
              supports_folders=use_imap,
              title=i18n("List %(folder)s for %(user)s") % 
                    { "folder": folder,
                  "user": (auth.user.name or auth.user.id)})

  index_html = List

  def Read(self, REQUEST, index, folder="INBOX"):
    "Read single message"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msg = mbox[index]
    self.markmsg(auth, msg)
    return self.genHTML(REQUEST, open(mail_template), folder=folder, folders=mbox.folders(),
              title=i18n("Read message"), msg=msg, index=index,
              supports_folders=use_imap,            
              message=MessageViewer(msg, folder=folder, inlineimages=auth.user.inlineimages))

  def GetPart(self, REQUEST, RESPONSE, index, num, folder="INBOX"):
    "Get decodes message part"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msg = mbox[index]
    if num != "":
      part = getMIMEPart(msg, num)
    else:
      part = msg
    RESPONSE.setHeader("Content-Type", part.gettype())
    if part.filename:
      RESPONSE.setHeader("Content-Disposition", 
                 'filename="%s"' % part.filename)
    return part.decode()

  def Compose(self, REQUEST, To="", Subject="", Cc="", Bcc=""):
    "Compose new message"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    if auth.user.signature:
      sig = "\n\n-- \n%s" % auth.user.signature
    else: sig = ""
    sender = self.getSender(auth)
    return self.genHTML(REQUEST, open(compose_template), body=sig,
              sender=sender, to=To, cc=Cc, bcc=Bcc, subject=Subject, 
              title=i18n("Compose new message"))


  def Reply(self, REQUEST, index, toAll=0, folder="INBOX"):
    "Reply to message" # XXX: make use of Reply-To header!
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msg = mbox[index]
    self.markmsg(auth, msg)
    if toAll: 
      cc = msg.ToList or ""
      if cc: cc = cc + ", "
      cc = cc  + msg.CcList or ""
    else: cc = ""
    subject = msg.Subject
    if subject and len(subject) >= 3:
      if lower(subject)[:3] not in ["re:", "aw:"]:
        subject = i18n("Re: %s") % subject
    else: subject = i18n("Re: %s") % subject
    sender = self.getSender(auth)
    return self.genHTML(REQUEST, open(compose_template), title=i18n("Reply to message"), 
              sender=sender, cc=cc, to=msg.Sender, subject=subject, 
              inreplyto=msg.getheader("message-id", ""),
              body=quotedtext(repr(MessageViewer(msg,folder=folder, inlineimages=0))))

  def ReplyAll(self, REQUEST, index, folder="INBOX"):
    "Reply to all recipients from message"
    return self.Reply(REQUEST, index, toAll=1, folder=folder)
  
  def ViewRaw(self, REQUEST, RESPONSE, index, headers=0, folder="INBOX"):
    "Show plain message"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msg = mbox[index,headers]
    self.markmsg(auth, msg)
    RESPONSE.setHeader("Content-type", "text/plain")
    return str(msg)

  def Forward(self, REQUEST, index, folder="INBOX"):
    "Forward a message"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    msg = mbox[index]
    self.markmsg(auth, msg)
    sender = self.getSender(auth)
    return self.genHTML(
      REQUEST, open(compose_template), title=i18n("Forward message"), 
      sender=sender, subject=i18n("Fwd: %s - %s") % (msg.FromAddr, msg.Subject),
      body=quotedtext(repr(MessageViewer(msg, folder=folder, inlineimages=0))))      

  def Action(self, REQUEST, RESPONSE, action="", 
         index=None, folder="INBOX", destination="", delete=""):
    "Do something with selected mails"
    if delete != "": action = "delete"
    if action == "delete": delflag, copyflag, msgtext, destination = 1, 0, 3, folder
    elif action == "copy": delflag, copyflag, msgtext = 0, 1, 5
    elif action == "move": delflag, copyflag, msgtext = 1, 1, 6
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)[folder]
    if index != None:
      msg = mbox[index,1]
      if copyflag: mbox.append(index, destination)
      if delflag: del mbox[index]
      self.unmarkmsg(auth, msg)
    elif destination != "":
      import cgi, re
      numpat = re.compile("^del([0-9]*)")
      form = cgi.FieldStorage()
      dellist = []
      for i in form.keys():
        if i == "delete": continue # XXX quick hack
        m = numpat.match(i)
        if m: dellist.append(int(m.group(1)))
      dellist.sort(); dellist.reverse()
      for i in dellist:
        msg = mbox[i, 1]        
        if copyflag: mbox.append(i, destination)
        if delflag: del mbox[i]
        self.unmarkmsg(auth, msg)
    RESPONSE.redirect("%s/MailBox/index_html?message:int=%s&folder=%s" % (
      REQUEST["SESSION_URL"], msgtext, destination))

  def Move(self, REQUEST, RESPONSE, index=None, folder="INBOX", destinaton=""):
    "Move messages"
    return self.Action(REQUEST, RESPONSE, "move", index, folder)

  def Copy(self, REQUEST, RESPONSE, index=None, folder="INBOX", destinaton=""):
    "Copy messages"
    return self.Action(REQUEST, RESPONSE, "copy", index, folder)

  def Delete(self, REQUEST, RESPONSE, index=None, folder="INBOX"):
    "Delete messages"
    return self.Action(REQUEST, RESPONSE, "delete", index, folder)

  def Bounce(self, REQUEST, index, folder="INBOX"):
    "Bounce messages"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    return self.genHTML(REQUEST, open(bounce_template),
              title=i18n("Bounce message"), index=index)

  def SendMsg(self, REQUEST, RESPONSE, To, index):
    "Bounce message to recipient"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    inbox = self.getFolder(auth, "inbox")
    msg = inbox[index]
    sender = self.getSender(auth)
    from sendmail import *
    errors = sendMessage(sender, To, msg)
    if errors: 
      return self.genHTML(REQUEST, open(sent_template),
                title=i18n("Sent mail"), failed=errors)
    else:
      RESPONSE.redirect(
        "%s/MailBox/index_html?message:int=%s" % (
        REQUEST["SESSION_URL"], 5))
      
  def Send(self, REQUEST, RESPONSE, to, cc="", bcc="", subject="", body="", attach=None, InReplyTo=None):
    "Send mail"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    if InReplyTo: InReplyTo = urlunquote(InReplyTo)
    from sendmail import *
    filename = getattr(attach, "filename", "")
    if filename == "": attach = None # XXX: fix for Opera/Linux
    sender = self.getSender(auth)
    errors = sendmail(sender, to, cc, bcc,
              subject, body, attach, filename, InReplyTo)
    if errors: 
      return self.genHTML(REQUEST, open(sent_template),
                title=i18n("Sent mail"), failed=errors)
    else:
      RESPONSE.redirect(
        "%s/MailBox/index_html?message:int=%s" % (
        REQUEST["SESSION_URL"], 2))

  def Goto(self, REQUEST, RESPONSE):
    "Goto URL (necessary to hide REFERRER information"
    url = urlunquote(REQUEST.get("QUERY_STRING", ""))
    RESPONSE.redirect(url)

  def Folder(self, REQUEST, RESPONSE, action, name, folder):
    "Folder management"
    auth = self.bobomail.Authentication(REQUEST["SESSION"])
    if not auth.relogin(): return self.authError()
    mbox = self.getMailbox(auth)
    if action == "create":
      name = "%s/%s" % (pathsplit(folder)[0], name)
      try:
        mbox.append(name)
        folder = name
        msgtext = 7
      except:
        return self.error(i18n("Folder could not be created"),
                  i18n("Probably you used invalid charakters") + \
                  "<br>%s" % mbox.last_exception)        
    elif action == "rename":
      name = "%s/%s" % (pathsplit(folder)[0], name)
      try:
        mbox[folder] = name
        msgtext = 8
        folder = name
      except:
        return self.error(i18n("Folder could not be renamed"),
                  i18n("Probably you used invalid charakters") + \
                  "<br>%s" % mbox.last_exception)        
    elif action == "delete":
      if name == os.path.split(folder)[1]:
        try:
          mbox.remove(folder)
          folder = "INBOX"
          msgtext = 9
        except:
          return self.error(i18n("Folder could not be removed"),
                    i18n("Perhaps the folder is already removed") + \
                    "<br>%s" % mbox.last_exception)
      else:
        return self.error(
          i18n("Folder NOT deleted"), i18n("You didn't type the name to confirm"))
    RESPONSE.redirect(
      "%s/MailBox/index_html?message:int=%s&folder=%s" % (
      REQUEST["SESSION_URL"], msgtext, folder))
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.