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 = '[EMAIL PROTECTED]' fromemail = '[EMAIL PROTECTED]' 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\nSending 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()
-- http://mail.python.org/mailman/listinfo/python-list