473,503 Members | 1,677 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

1 New Member
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 2405
bartonc
6,596 Recognized Expert Expert
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
8350
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
3340
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
1846
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
2677
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
2508
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
2058
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
2885
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
1111
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
1526
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
6829
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
7202
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7084
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
7278
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
7328
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7458
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...
0
5578
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5013
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3154
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.