Six Years of Deep in the Code

six years old

In looking through my older posts, I realized that I wrote my first post, Guide for the Perplexed, six years ago yesterday.

I don’t have as much time to write as much as did during the first couple of years of this blog; I generally write two posts per month now. Even so, I hope that these posts continue to do what I originally intended when I started writing them back in 2012 – both to make available useful information that is not easily found in one place, and by combining different techniques to synthesize processes that create more value than the sums of their parts.

I have received many comments and suggestions over the years, and I have found almost all of them to be not only constructive in nature, but that they have also helped correct things about which I was mistaken and also to help provide clarity when my explanation was not as clear as it could have been. Thanks for these, and keep the comments coming – they are welcome!

The things that have changed the most are the technologies that I’ve used. When I started, I primarily wrote about ASP.NET (mostly VB.NET, with some C# .NET), and SQL Server. Though I still write about SQL Server often, I find that I tend to work with other front-end technologies more often than ASP.NET now – especially JavaScript with or without jQuery.

I am planning on getting involved with more open-source technology where possible – R seems to be a good choice. Much like Python and jQuery, I think it will be more widely used in the coming years.

Thanks for reading!

Sending an Email with Attachments using Python – Checks for Attachments Before Sending

This is an update to a script I put together several years ago which needed some minor changes to prevent the email from being sent if there were no attachments. Also, there was a bug that would send the email whether attachments were present or not due to the presence of the archive folder in the searched folder. This code should correct that. I changed the script as little as possible, so some may criticize the duplicate if statement. If I have time, I will correct this in the near future. Even so, it should work fine as written.

# Adapted from https://gist.github.com/4009671 and other sources by David Young
# added directory searching functionality to add all files in folder
# disabled username / password logon for use in our Exchange environment


######### Setup your stuff here #######################################
servername='ServerName'
path='//' + servername + '/PathUnderServerName' # location of files
archiveFolderName = 'archive' # name of folder under path where files will be archived

host = 'smtp.example.com' # specify port, if required, using a colon and port number following the hostname

fromaddr = 'yourfromaddress@example.com' # must be a vaild 'from' address in your environment
toaddr  = "yourtoaddress@example.com"
replyto = fromaddr # unless you want a different reply-to

# username = 'username' # not used in our Exchange environment
# password = 'password' # not used in our Exchange environment

msgsubject = 'Your message regarding server named ' + servername

htmlmsgtext = """

Files present on server named """ + servername + """ are attached and have been archived.

""" # text with appropriate HTML tags ######### In normal use nothing changes below this line ############### import smtplib, os, sys, shutil from datetime import date from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email import Encoders from HTMLParser import HTMLParser archivePath = os.path.join(path, archiveFolderName) # full path where files will be archived if not os.path.exists(archivePath): # create archive folder if it doesn't exist os.makedirs(archivePath) print 'Archive folder created at ' + archivePath + '.' # A snippet - class to strip HTML tags for the text version of the email class MLStripper(HTMLParser): def __init__(self): self.reset() self.fed = [] def handle_data(self, d): self.fed.append(d) def get_data(self): return ''.join(self.fed) def strip_tags(html): s = MLStripper() s.feed(html) return s.get_data() ######################################################################## try: # Make text version from HTML - First convert tags that produce a line break to carriage returns msgtext = htmlmsgtext.replace('
',"\r").replace('
',"\r").replace('

',"\r") # Then strip all the other tags out msgtext = strip_tags(msgtext) # necessary mimey stuff msg = MIMEMultipart() msg.preamble = 'This is a multi-part message in MIME format.\n' msg.epilogue = '' body = MIMEMultipart('alternative') body.attach(MIMEText(msgtext)) body.attach(MIMEText(htmlmsgtext, 'html')) msg.attach(body) attachments = os.listdir(path) if 'attachments' in globals() and len(attachments) > 1: # are there attachments? for filename in attachments: if os.path.isfile(os.path.join(path, filename)): f = os.path.join(path, filename) part = MIMEBase('application', "octet-stream") part.set_payload( open(f,"rb").read() ) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f)) msg.attach(part) msg.add_header('From', fromaddr) msg.add_header('To', toaddr) msg.add_header('Subject', msgsubject) msg.add_header('Reply-To', replyto) # The actual email sendy bits server = smtplib.SMTP(host) server.set_debuglevel(False) # set to True for verbose output # Comment this block and uncomment the below try/except block if TLS or user/pass is required. if 'attachments' in globals() and len(attachments) > 1: # are there attachments? server.sendmail(msg['From'], [msg['To']], msg.as_string()) print 'Email sent.' #print len(attachments)-1 else: print 'No attachments found.' server.quit() # bye bye # try: # # If TLS is used # server.starttls() # server.login(username,password) # server.sendmail(msg['From'], [msg['To']], msg.as_string()) # print 'Email sent.' # server.quit() # bye bye # except: # # if tls is set for non-tls servers you would have raised an exception, so.... # server.login(username,password) # server.sendmail(msg['From'], [msg['To']], msg.as_string()) # print 'Email sent.' # server.quit() # bye bye except: print "Email NOT sent to %s successfully. ERR: %s %s %s " % (str(toaddr), str(sys.exc_info()[0]), str(sys.exc_info()[1]), str(sys.exc_info()[2]) ) #just in case try: if 'attachments' in globals() and len(attachments) > 1: # are there attachments? for filename in attachments: if os.path.isfile(os.path.join(path, filename)): f1 = os.path.join(path, filename) x = filename.find('.') filename2 = filename[:x] + '_' + str(date.today()) + filename[x:] f2 = os.path.join(path, filename2) os.rename(f1, f2) print "File " + filename + " renamed to " + filename2 + "." shutil.move(f2, archivePath) print "File " + filename2 + " moved to " + archivePath + "." except: print "Files not successfully renamed and/or archived."