473,395 Members | 1,386 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

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

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


Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/python
  2.  
  3. import wx
  4. import smtplib
  5. from email import Encoders
  6. from email.MIMEMultipart import MIMEMultipart
  7. from email.Utils import COMMASPACE, formatdate
  8. from email.MIMEBase import MIMEBase
  9. from email.MIMEText import MIMEText
  10. import os
  11.  
  12. # set a few variables to make testing less tedious
  13.  
  14. # you need to set your smtp server domain name
  15. smtp_server = 'smtp.your_isp_domain.com'
  16.  
  17. toemail = 'toemail@somedomain.org'
  18. fromemail = 'fromemail@anotherdomain.org'
  19. subject = 'Testing python smtplib module'
  20. emailmsg = 'How do I determine the number of bytes that have been ' +\
  21. 'forwarded whilst the e-mail is being sent?\n\nSending large (or many) ' +\
  22. 'attachments may take some time, and I\'d like to use a gauge ' +\
  23. 'control to give users an indication of the percentage of ' +\
  24. 'the e-mail that has already been sent.\n\nThe smtplib module relies ' +\
  25. 'on sockets, but I don\'t know how to use python sockets to ' +\
  26. 'send an e-mail with attachments and concurrently monitor the ' +\
  27. 'number of bytes that have already been sent.\n\nHelp !'
  28.  
  29. # attachment file
  30. attachment = 'C:\\Documents and Settings\\-\\Desktop\\test.zip'
  31. #attachment = '/home/user1/Desktop/test.zip'
  32.  
  33.  
  34. # variable to hold bytes that have been sent
  35. bytes_sent = 0
  36.  
  37.  
  38.  
  39.  
  40. class MainFrame(wx.Frame):
  41.     def __init__(self, *args, **kwargs):
  42.         wx.Frame.__init__(self, *args, **kwargs)
  43.         self.SetSize(wx.Size(750,550))
  44.         self.SetTitle('Monitoring the number of bytes sent during ' +\
  45.         'a python e-mail send  -  How ?')
  46.  
  47.         panel = wx.Panel(self)
  48.  
  49.         vertsizer = wx.BoxSizer(wx.VERTICAL)
  50.  
  51.         flexsizer = wx.FlexGridSizer(rows=8, cols=2, hgap=10, vgap=10)
  52.         flexsizer.AddGrowableCol(1)
  53.         flexsizer.AddGrowableRow(4)
  54.  
  55.         tolabel = wx.StaticText(panel, -1, "To E-mail Address:")
  56.         flexsizer.Add(tolabel,0,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
  57.         self.toemailaddress = wx.TextCtrl(panel)
  58.         flexsizer.Add(self.toemailaddress,0,wx.EXPAND)
  59.  
  60.         fromlabel = wx.StaticText(panel, -1, "From E-mail Address:")
  61.         flexsizer.Add(fromlabel,0,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
  62.         self.fromemailaddress = wx.TextCtrl(panel)
  63.         flexsizer.Add(self.fromemailaddress,0,wx.EXPAND)
  64.  
  65.         attachmentbutton = wx.Button(panel, 1001, "File Attachment")
  66.         attachmentbutton.Bind(wx.EVT_BUTTON, self.SelectAttachmentFile)
  67.         flexsizer.Add(attachmentbutton,0,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
  68.         self.attachmenteditbox = wx.TextCtrl(panel, style = wx.TE_CENTRE)
  69.         self.attachmenteditbox.Disable()
  70.         flexsizer.Add(self.attachmenteditbox,0,wx.EXPAND)
  71.  
  72.         subjectlabel = wx.StaticText(panel, -1, "Subject:")
  73.         flexsizer.Add(subjectlabel,0,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
  74.         self.subject = wx.TextCtrl(panel)
  75.         flexsizer.Add(self.subject,0,wx.EXPAND)
  76.  
  77.         messagelabel = wx.StaticText(panel, -1, "E-mail Message:")
  78.         flexsizer.Add(messagelabel,0,wx.ALIGN_RIGHT)
  79.         self.emailmessage = wx.TextCtrl(panel, style = wx.TE_MULTILINE)
  80.         flexsizer.Add(self.emailmessage,1,wx.EXPAND)
  81.  
  82.         flexsizer.AddSpacer(wx.Size(1,1))
  83.  
  84.         self.gauge = wx.Gauge(panel)
  85.         self.gauge.SetRange(100)
  86.         self.gauge.SetValue(30)
  87.         sendbutton = wx.Button(panel, 1001, "Send E-mail")
  88.         sendbutton.Bind(wx.EVT_BUTTON, self.SendTheEmail)
  89.         hsizer = wx.BoxSizer(wx.HORIZONTAL)
  90.         hsizer.Add(self.gauge,1,wx.RIGHT,15)
  91.         hsizer.Add(sendbutton,0,wx.ALIGN_CENTER_VERTICAL)
  92.         flexsizer.Add(hsizer,0,wx.EXPAND)
  93.  
  94.         byteslabel1 = wx.StaticText(panel, -1, "Bytes to Send:")
  95.         self.bytestosend = wx.StaticText(panel, -1, "0")
  96.         flexsizer.Add(byteslabel1,0,wx.ALIGN_RIGHT)
  97.         flexsizer.Add(self.bytestosend,0,wx.EXPAND)
  98.  
  99.         byteslabel2 = wx.StaticText(panel, -1, "Bytes Sent:")
  100.         self.bytessent = wx.StaticText(panel, -1, "0")
  101.         flexsizer.Add(byteslabel2,0,wx.ALIGN_RIGHT)
  102.         flexsizer.Add(self.bytessent,0,wx.EXPAND)
  103.  
  104.  
  105.         vertsizer.Add(flexsizer,1, wx.EXPAND|wx.ALL,30)
  106.  
  107.         # place values into appropriate text fields
  108.         # (these values can be initialized at the top of this script)
  109.  
  110.         self.toemailaddress.SetValue(toemail)
  111.         self.fromemailaddress.SetValue(fromemail)
  112.         self.subject.SetValue(subject)
  113.         self.emailmessage.SetValue(emailmsg)
  114.  
  115.         if os.path.exists(os.path.abspath(attachment)):
  116.             self.attachmenteditbox.SetValue(\
  117.             os.path.split(os.path.abspath(attachment))[1])
  118.  
  119.         panel.SetSizer(vertsizer)
  120.  
  121.         self.bytestosend.SetLabel(str(self.GetMimeSize()))
  122.  
  123.  
  124.  
  125.     # select an attachment file for the e-mail
  126.     def SelectAttachmentFile(self, event):
  127.  
  128.         filedlgbox = wx.FileDialog(self,\
  129.             message="Select  an Attachment  File", \
  130.             defaultDir=os.getcwd(), \
  131.             defaultFile='', \
  132.             wildcard="Any File (*.*)|*.*", \
  133.             style=wx.OPEN | wx.CHANGE_DIR | wx.HIDE_READONLY)
  134.  
  135.         if filedlgbox.ShowModal() == wx.ID_OK:
  136.             global attachment
  137.             attachment = filedlgbox.GetFilenames()[0].strip()
  138.             self.attachmenteditbox.SetValue(os.path.split(attachment)[1])
  139.  
  140.         filedlgbox.Destroy()
  141.  
  142.         self.bytestosend.SetLabel(str(self.GetMimeSize()))
  143.  
  144.         event.Skip()
  145.  
  146.  
  147.  
  148.     def GetMimeSize(self):
  149.  
  150.         # get size of current e-mail mime object
  151.  
  152.         tempmime = MIMEMultipart()
  153.         tempmime['To'] = self.toemailaddress.GetValue().strip()
  154.         tempmime['From'] = self.fromemailaddress.GetValue().strip()
  155.         tempmime['Subject'] = self.subject.GetValue().strip()
  156.  
  157.         # add the e-mail message to the mime object
  158.         tempmime.attach(MIMEText(self.emailmessage.GetValue()))
  159.  
  160.         # add an attachment file to the mime object if selected
  161.         if attachment.strip() != '':
  162.             thisfile = os.path.abspath(attachment)
  163.             if os.path.exists(thisfile):
  164.                 attachmentmime = MIMEBase('application', "octet-stream")
  165.                 attachmentmime.set_payload( open(thisfile,"rb").read())
  166.                 Encoders.encode_base64(attachmentmime)
  167.                 attachmentmime.add_header('Content-Disposition',\
  168.                 'attachment; filename="%s"' % os.path.basename(thisfile))
  169.                 tempmime.attach(attachmentmime)
  170.  
  171.         mimesize = len(tempmime.as_string())
  172.  
  173.         tempmime = None
  174.  
  175.         return mimesize
  176.  
  177.  
  178.     # send the e-mail using python's smtplib module
  179.     def SendTheEmail(self, event):
  180.  
  181.         # how can I determine the number of bytes that have
  182.         # been forwarded whilst the e-mail is being sent ?
  183.         global bytes_sent
  184.         bytes_sent = 0
  185.  
  186.         # set gauge value to zero - max value = 100 (%)
  187.         self.gauge.SetValue(0)
  188.  
  189.         self.bytestosend.SetLabel(str(self.GetMimeSize()))
  190.         self.bytessent.SetLabel('0')
  191.  
  192.         # create a multi-part mime object for the
  193.         # e-mail message and file attachment
  194.  
  195.         thismime = MIMEMultipart()
  196.         thismime['To'] = self.toemailaddress.GetValue().strip()
  197.         thismime['From'] = self.fromemailaddress.GetValue().strip()
  198.         thismime['Subject'] = self.subject.GetValue().strip()
  199.  
  200.         # add the e-mail message to the mime object
  201.         thismime.attach(MIMEText(self.emailmessage.GetValue()))
  202.  
  203.         # add an attachment file to the mime object if selected
  204.         if attachment.strip() != '':
  205.             thisfile = os.path.abspath(attachment)
  206.             if os.path.exists(thisfile):
  207.                 attachmentmime = MIMEBase('application', "octet-stream")
  208.                 attachmentmime.set_payload( open(thisfile,"rb").read())
  209.                 Encoders.encode_base64(attachmentmime)
  210.                 attachmentmime.add_header('Content-Disposition',\
  211.                 'attachment; filename="%s"' % os.path.basename(thisfile))
  212.                 thismime.attach(attachmentmime)
  213.             else:
  214.                 dlg = wx.MessageDialog(self,\
  215.                 message='Attachment file ' + thisfile + ' is missing.',\
  216.                 caption='Attachment Missing',style=wx.OK|\
  217.                 wx.ICON_INFORMATION)
  218.                 dlg.ShowModal()
  219.                 dlg.Destroy()
  220.  
  221.         # send the e-mail
  222.         smtpobj = smtplib.SMTP(smtp_server)
  223.         smtpobj.sendmail(self.fromemailaddress.GetValue().strip(), \
  224.                             self.toemailaddress.GetValue().strip(), \
  225.                             thismime.as_string())
  226.  
  227.         smtpobj.close()
  228.  
  229.  
  230.         event.Skip()
  231.  
  232.  
  233.  
  234. if __name__ == '__main__':
  235.     app = wx.App()
  236.     theframe = MainFrame(None)
  237.     theframe.Show()
  238.     app.MainLoop()
  239.  
  240.  
  241.  
Dec 4 '06 #1
1 2391
bartonc
6,596 Expert 4TB
I'm looking into socket byte counts. In the meantime, one line stuck out as I was reading your code:
Expand|Select|Wrap|Line Numbers
  1.         tempmime = None
  2.  
doesn't free up memory immediately. It does set the refcount to zero (if there are no other reference) by reseting the value of the temporary variable to None, so it will eventually be garbage collected. Your intention was probably to
Expand|Select|Wrap|Line Numbers
  1.         del tempmime
  2.  
which frees up memory immediately.
Dec 6 '06 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

36
by: Dag | last post by:
Is there a python module that includes functions for working with prime numbers? I mainly need A function that returns the Nth prime number and that returns how many prime numbers are less than N,...
21
by: Nancy | last post by:
Hi, Guys, Is there any other way to use python or mod_python writing a web page? I mean, not use "form.py/email", no SMTP server. <form action="form.py/email" method="POST"> ... Thanks a lot. ...
0
by: Jay Blanchard | last post by:
-----Original Message----- From: Moritz Steiner =20 Sent: Wednesday, July 16, 2003 10:46 AM To: Jay Blanchard Subject: AW: monitoring I want to see: Number of queries =20
5
by: Mike Meyer | last post by:
I've found a fair number of systems/network monitoring tools (things like Big Brother, Big Sister, cricket, etc.) written in Perl. I'm curious if there are any written in Python. Thanks, <mike...
2
by: Jonesgj | last post by:
Hi, I have a test box which I would like to monitor CPU usage and run queue during the day. I don't want to buy any 3rd party tool, if I can do it easily, as I only need to monitor the box's...
2
by: Dave | last post by:
Hello, I am trying to write an application that will talk to an SMTP server using sockets. I can connect to the server just fine, then I can receive the first message from the server. I can then...
2
by: wwwmike | last post by:
My applications (ASP.NET 2.0 /IIS 6) get restarted almost every 20 mintues. When asking my dear provider, he/she replied that I should have a closer look into my source code. Unfortunatelly they...
1
by: Alex | last post by:
I would like to write a VB.NET 2.0 program that is scheduled and checks a SMTP server, possibly via POP3. This parser will check for new messages, bad messages, and parse the text contained within...
3
by: Gilles Ganault | last post by:
Hello I'd like to monitor connections to a remote SSH and web server. Does someone have some code handy that would try to connect every 5mn, and print an error if the script can't connect? ...
2
by: Eric E | last post by:
Hello All - I am using python to send an email with a large zip file as an attachment. I successfully sent a 52M attachment. If I try to send a 63M attachment or larger, the message never gets...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.