472,368 Members | 2,666 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,368 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 2282
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...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
0
by: jack2019x | last post by:
hello, Is there code or static lib for hook swapchain present? I wanna hook dxgi swapchain present for dx11 and dx9.

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.