473,756 Members | 3,211 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 2442
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
8400
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, but a prime number tester would also be nice. I'm dealing with numbers in the 10^6-10^8 range so it would have to fairly efficient Dag
21
3381
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. Nancy W
0
1867
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
2688
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 -- Mike Meyer <mwm@mired.org> http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
2
2525
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 performance over a week. I thought I could just create a .Net app or service with a timer that gets back this data every so many minutes..
2
2073
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 send out a command to the server, but after that the thing just hangs when I am waiting for a response. I can't understand why this is happening. I am new to this language, so this might be something obvious that I am overlooking. Any help would...
2
2915
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 did not give me any hints WHERE and WHY I have all these restarts. Granted, I pay 20USD/month and they want for sure not spend hours for detecting my problem. I suspect that my ADO.NET calls to SQL Server have something to do with
1
1122
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 the email and header. My main goal is to have many email addresses created on the fly and they all get routed to the same location which my program will detect which email address an email was sent to. Attachments will also need to be parsed and...
3
1543
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? Thank you.
2
7003
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 through. I do not get any errors in my python code. I pasted my python code below. from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart from email import Encoders
0
9275
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10034
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9872
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9843
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9713
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7248
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5142
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3805
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2666
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.