Monitoring number of smtp bytes sent through python e-mail socket

Discussion in 'Python' started by William Connery, Dec 5, 2006.

  1. Hi,

    I have a small python program with e-mail capabilities that I have
    pieced together from code snippets found on the internet.

    The program uses the smtplib module to successfully send an e-mail with
    an attachment.

    I want to give users an indication of the percentage of the e-mail that
    has already been sent so as to avoid frustration when dealing with large
    attachments or a slow smtp server. But the smtplib module doesn't seem
    to provide access to the number of bytes that have already been sent.

    Can anyone help, or provide a working example of sending an e-mail
    attachment using basic python sockets whilst having access to the number
    of bytes that have already been sent through the socket?

    Many thanks.

    William Connery


    #!/usr/bin/python

    import wx
    import smtplib
    from email import Encoders
    from email.MIMEMultipart import MIMEMultipart
    from email.Utils import COMMASPACE, formatdate
    from email.MIMEBase import MIMEBase
    from email.MIMEText import MIMEText
    import os

    # set a few variables to make testing less tedious

    # you need to set your smtp server domain name
    smtp_server = 'smtp.your_isp_domain.com'

    toemail = ''
    fromemail = ''
    subject = 'Testing python smtplib module'
    emailmsg = 'How do I determine the number of bytes that ' +\
    'have been forwarded whilst the e-mail is being sent ?\n\n' +\
    'Sending large (or many) attachments may take some ' +\
    'time, and I\'d like to use a gauge control to give users ' +\
    'an indication of the percentage of the e-mail that has ' +\
    'already been sent.\n\nThe smtplib module relies on ' +\
    'sockets, but I don\'t know how to use python sockets ' +\
    'to send an e-mail with attachments and concurrently ' +\
    'monitor the number of bytes that have already been ' +\
    'sent.\n\nHelp !'

    # attachment file
    attachment = 'C:\\Documents and Settings\\-\\Desktop\\test.zip'
    #attachment = '/home/user1/Desktop/test.zip'


    # variable to hold bytes that have been sent
    bytes_sent = 0




    class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
    wx.Frame.__init__(self, *args, **kwargs)
    self.SetSize(wx.Size(750,550))
    self.SetTitle('Monitoring the number of bytes sent during ' +\
    'a python e-mail send - How ?')

    panel = wx.Panel(self)

    vertsizer = wx.BoxSizer(wx.VERTICAL)

    flexsizer = wx.FlexGridSizer(rows=8, cols=2, hgap=10, \
    vgap=10)
    flexsizer.AddGrowableCol(1)
    flexsizer.AddGrowableRow(4)

    tolabel = wx.StaticText(panel, -1, "To E-mail Address:")
    flexsizer.Add(tolabel,0,wx.ALIGN_RIGHT|\
    wx.ALIGN_CENTER_VERTICAL)
    self.toemailaddress = wx.TextCtrl(panel)
    flexsizer.Add(self.toemailaddress,0,wx.EXPAND)

    fromlabel = wx.StaticText(panel, -1, "From E-mail Address:")
    flexsizer.Add(fromlabel,0,wx.ALIGN_RIGHT|\
    wx.ALIGN_CENTER_VERTICAL)
    self.fromemailaddress = wx.TextCtrl(panel)
    flexsizer.Add(self.fromemailaddress,0,wx.EXPAND)

    attachmentbutton = wx.Button(panel, 1001, "File Attachment")
    attachmentbutton.Bind(wx.EVT_BUTTON, \
    self.SelectAttachmentFile)
    flexsizer.Add(attachmentbutton,0,wx.ALIGN_RIGHT|\
    wx.ALIGN_CENTER_VERTICAL)
    self.attachmenteditbox = wx.TextCtrl(panel,\
    style = wx.TE_CENTRE)
    self.attachmenteditbox.Disable()
    flexsizer.Add(self.attachmenteditbox,0,wx.EXPAND)

    subjectlabel = wx.StaticText(panel, -1, "Subject:")
    flexsizer.Add(subjectlabel,0,wx.ALIGN_RIGHT|\
    wx.ALIGN_CENTER_VERTICAL)
    self.subject = wx.TextCtrl(panel)
    flexsizer.Add(self.subject,0,wx.EXPAND)

    messagelabel = wx.StaticText(panel, -1, "E-mail Message:")
    flexsizer.Add(messagelabel,0,wx.ALIGN_RIGHT)
    self.emailmessage = wx.TextCtrl(panel, \
    style = wx.TE_MULTILINE)
    flexsizer.Add(self.emailmessage,1,wx.EXPAND)

    flexsizer.AddSpacer(wx.Size(1,1))

    self.gauge = wx.Gauge(panel)
    self.gauge.SetRange(100)
    self.gauge.SetValue(30)
    sendbutton = wx.Button(panel, 1001, "Send E-mail")
    sendbutton.Bind(wx.EVT_BUTTON, self.SendTheEmail)
    hsizer = wx.BoxSizer(wx.HORIZONTAL)
    hsizer.Add(self.gauge,1,wx.RIGHT,15)
    hsizer.Add(sendbutton,0,wx.ALIGN_CENTER_VERTICAL)
    flexsizer.Add(hsizer,0,wx.EXPAND)

    byteslabel1 = wx.StaticText(panel, -1, "Bytes to Send:")
    self.bytestosend = wx.StaticText(panel, -1, "0")
    flexsizer.Add(byteslabel1,0,wx.ALIGN_RIGHT)
    flexsizer.Add(self.bytestosend,0,wx.EXPAND)

    byteslabel2 = wx.StaticText(panel, -1, "Bytes Sent:")
    self.bytessent = wx.StaticText(panel, -1, "0")
    flexsizer.Add(byteslabel2,0,wx.ALIGN_RIGHT)
    flexsizer.Add(self.bytessent,0,wx.EXPAND)


    vertsizer.Add(flexsizer,1, wx.EXPAND|wx.ALL,30)

    # place values into appropriate text fields
    # (these values can be initialized at the top of this script)

    self.toemailaddress.SetValue(toemail)
    self.fromemailaddress.SetValue(fromemail)
    self.subject.SetValue(subject)
    self.emailmessage.SetValue(emailmsg)

    if os.path.exists(os.path.abspath(attachment)):
    self.attachmenteditbox.SetValue(\
    os.path.split(os.path.abspath(attachment))[1])

    panel.SetSizer(vertsizer)

    self.bytestosend.SetLabel(str(self.GetMimeSize()))



    # select an attachment file for the e-mail
    def SelectAttachmentFile(self, event):

    filedlgbox = wx.FileDialog(self,\
    message="Select an Attachment File", \
    defaultDir=os.getcwd(), \
    defaultFile='', \
    wildcard="Any File (*.*)|*.*", \
    style=wx.OPEN | wx.CHANGE_DIR | \
    wx.HIDE_READONLY)

    if filedlgbox.ShowModal() == wx.ID_OK:
    global attachment
    attachment = filedlgbox.GetFilenames()[0].strip()
    self.attachmenteditbox.SetValue(\
    os.path.split(attachment)[1])

    filedlgbox.Destroy()

    self.bytestosend.SetLabel(str(self.GetMimeSize()))

    event.Skip()



    def GetMimeSize(self):

    # get size of current e-mail mime object

    tempmime = MIMEMultipart()
    tempmime['To'] = self.toemailaddress.GetValue().strip()
    tempmime['From'] = self.fromemailaddress.GetValue().strip()
    tempmime['Subject'] = self.subject.GetValue().strip()

    # add the e-mail message to the mime object
    tempmime.attach(MIMEText(self.emailmessage.GetValue()))

    # add an attachment file to the mime object if selected
    if attachment.strip() != '':
    thisfile = os.path.abspath(attachment)
    if os.path.exists(thisfile):
    attachmentmime = MIMEBase('application', \
    "octet-stream")
    attachmentmime.set_payload(\
    open(thisfile,"rb").read())
    Encoders.encode_base64(attachmentmime)
    attachmentmime.add_header('Content-Disposition',\
    'attachment; filename="%s"' % \
    os.path.basename(thisfile))
    tempmime.attach(attachmentmime)

    mimesize = len(tempmime.as_string())

    tempmime = None

    return mimesize


    # send the e-mail using python's smtplib module
    def SendTheEmail(self, event):

    # how can I determine the number of bytes that have
    # been forwarded whilst the e-mail is being sent ?
    global bytes_sent
    bytes_sent = 0

    # set gauge value to zero - max value = 100 (%)
    self.gauge.SetValue(0)

    self.bytestosend.SetLabel(str(self.GetMimeSize()))
    self.bytessent.SetLabel('0')

    # create a multi-part mime object for the
    # e-mail message and file attachment

    thismime = MIMEMultipart()
    thismime['To'] = self.toemailaddress.GetValue().strip()
    thismime['From'] = self.fromemailaddress.GetValue().strip()
    thismime['Subject'] = self.subject.GetValue().strip()

    # add the e-mail message to the mime object
    thismime.attach(MIMEText(self.emailmessage.GetValue()))

    # add an attachment file to the mime object if selected
    if attachment.strip() != '':
    thisfile = os.path.abspath(attachment)
    if os.path.exists(thisfile):
    attachmentmime = MIMEBase('application', \
    "octet-stream")
    attachmentmime.set_payload(\
    open(thisfile,"rb").read())
    Encoders.encode_base64(attachmentmime)
    attachmentmime.add_header('Content-Disposition',\
    'attachment; filename="%s"' % \
    os.path.basename(thisfile))
    thismime.attach(attachmentmime)
    else:
    dlg = wx.MessageDialog(self,\
    message='Attachment file ' + thisfile + ' is missing.',\
    caption='Attachment Missing',style=wx.OK|\
    wx.ICON_INFORMATION)
    dlg.ShowModal()
    dlg.Destroy()

    # send the e-mail
    smtpobj = smtplib.SMTP(smtp_server)
    smtpobj.sendmail(self.fromemailaddress.GetValue().strip(), \
    self.toemailaddress.GetValue().strip(), \
    thismime.as_string())

    smtpobj.close()


    event.Skip()



    if __name__ == '__main__':
    app = wx.App()
    theframe = MainFrame(None)
    theframe.Show()
    app.MainLoop()
    William Connery, Dec 5, 2006
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Curt_C [MVP]
    Replies:
    5
    Views:
    354
    Karim
    May 19, 2004
  2. Replies:
    34
    Views:
    13,180
  3. Replies:
    3
    Views:
    1,050
    Roedy Green
    Jan 24, 2006
  4. Alex Hunsley
    Replies:
    4
    Views:
    3,409
    Tim Williams (gmail)
    Jun 29, 2004
  5. Ashwin Rao
    Replies:
    2
    Views:
    1,036
    Martien Verbruggen
    Dec 3, 2009
Loading...

Share This Page