| 1 | import os | |
|---|---|---|
| 2 | import string | |
| 3 | import smtplib | |
| 4 | import platform | |
| 5 | import socket | |
| 6 | import tempfile | |
| 7 | import matplotlib | |
| 8 | import matplotlib.numerix as nx | |
| 9 | from email.MIMEImage import MIMEImage | |
| 10 | from email.MIMEText import MIMEText | |
| 11 | from email.MIMEMultipart import MIMEMultipart | |
| 12 | matplotlib.use('Agg') # force the antigrain backend | |
| 13 | from matplotlib import rc | |
| 14 | from matplotlib.backends.backend_agg import FigureCanvasAgg | |
| 15 | from matplotlib.figure import Figure | |
| 16 | from matplotlib.cbook import iterable | |
| 17 | from pylab import axes,pie,title,text,figure | |
| 18 | from xml.dom.minidom import Document | |
| 19 | #Requires Python 2.4 or higher | |
| 20 | ||
| 21 | def getUnixDriveInfo(): | |
| 22 | """ | |
| 23 | Execute the df -l command on Unix/Linux and return an array containing the filesystem information. | |
| 24 | ||
| 25 | @rtype: array | |
| 26 | @return: An array of tuples each containing the following filesystem information: (Filesystem,512-blocks,Used,Avail,Capacity,Mountpoint). | |
| 27 | """ | |
| 28 | filesystems = [] | |
| 29 | dfstdin, dfstdout, dfstderr = os.popen3("df -l") | |
| 30 | dfstdout.readline() #discard header | |
| 31 | for dfline in dfstdout.readlines(): | |
| 32 | filesystems.append([dfline.split()[0],dfline.split()[1],dfline.split()[2],dfline.split()[3],dfline.split()[4],dfline.split()[5]]) | |
| 33 | return filesystems | |
| 34 | ||
| 35 | def getHumanUnixDriveInfo(): | |
| 36 | """ | |
| 37 | Execute the df -l command on Unix/Linux and return an array containing the filesystem information. | |
| 38 | ||
| 39 | @rtype: array | |
| 40 | @return: An array of tuples each containing the following filesystem information: (Filesystem,512-blocks,Used,Avail,Capacity,Mountpoint). | |
| 41 | """ | |
| 42 | filesystems = [] | |
| 43 | dfstdin, dfstdout, dfstderr = os.popen3("df -l -h") | |
| 44 | dfstdout.readline() #discard header | |
| 45 | for dfline in dfstdout.readlines(): | |
| 46 | filesystems.append([dfline.split()[0],dfline.split()[1],dfline.split()[2],dfline.split()[3],dfline.split()[4],dfline.split()[5]]) | |
| 47 | return filesystems | |
| 48 | ||
| 49 | def getPlatformInfo(): | |
| 50 | bits, linkage = platform.architecture() | |
| 51 | machine = platform.machine() #i386 etc | |
| 52 | nodename = platform.node() #May not be fully qualified | |
| 53 | system = platform.system() #e.g. FreeBSD, Windows | |
| 54 | uname = platform.uname() | |
| 55 | pyversion = platform.python_version() | |
| 56 | pybuild = platform.python_build() | |
| 57 | ||
| 58 | def getInterfaceInfo(): | |
| 59 | return socket.getaddrinfo(socket.gethostname(), None) | |
| 60 | ||
| 61 | def filesystemsToHTML(filesystems): | |
| 62 | htmltable = "<table border=0 cellspacing=0 cellpadding=0>\n<tr><td width=120 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Filesystem</td>\n<td width=60 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Size</td>\n<td width=60 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Used</td>\n<td width=60 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Avail</td>\n<td width=60 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Capacity</td>\n<td width=200 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Mounted on</td>\n</tr>" | |
| 63 | for filesystem in filesystems: | |
| 64 | htmltable += "<tr><td bgcolor=#ABBCCF>" + filesystem[0] + "</td>\n<td bgcolor=#ABBCCF>" + filesystem[1] + "</td>\n<td bgcolor=#ABBCCF>" + filesystem[2] + "</td>\n<td bgcolor=#ABBCCF>" + filesystem[3] + "</td>\n<td bgcolor=#ABBCCF>" + filesystem[4] + "</td>\n<td bgcolor=#ABBCCF>" + filesystem[5] + "</td>\n</tr>" | |
| 65 | htmltable += "</table>" | |
| 66 | return htmltable | |
| 67 | ||
| 68 | def filesystemsToPie(filesystems): | |
| 69 | """ | |
| 70 | Convert a filesystems array (df output) into PNG pie charts. | |
| 71 | ||
| 72 | @type filesystems: array | |
| 73 | @param filesystems: An array of filesystem tuples | |
| 74 | ||
| 75 | @rtype: array | |
| 76 | @return: An array of temporary pie chart image file objects. | |
| 77 | """ | |
| 78 | PieCharts = [] | |
| 79 | for filesystem in filesystems: | |
| 80 | fig = figure(figsize=(1,1)) | |
| 81 | ax = axes([0.25, 0.25, 0.5, 0.5]) | |
| 82 | piecolors = 'red','#2F6297' | |
| 83 | fracs = [int(filesystem[2]),int(filesystem[3])] | |
| 84 | pie(fracs, explode=None,colors=piecolors, labels=None, autopct=None, shadow=True) | |
| 85 | title(filesystem[5],fontsize=10) | |
| 86 | text(0, -1.7, filesystem[4] + ' Used',horizontalalignment='center',verticalalignment='bottom',fontsize=9) | |
| 87 | canvas = FigureCanvasAgg(fig) | |
| 88 | fd = tempfile.NamedTemporaryFile(suffix='.png') | |
| 89 | canvas.print_figure(fd.name) | |
| 90 | PieCharts.append(fd) | |
| 91 | return PieCharts | |
| 92 | ||
| 93 | def filesystemsToXML(filesystems): | |
| 94 | """ | |
| 95 | Convert a filesystems array (df output) into XML. | |
| 96 | ||
| 97 | @type filesystems: array | |
| 98 | @param filesystems: An array of filesystem tuples | |
| 99 | ||
| 100 | @rtype: string | |
| 101 | @return: An XML string containing the FileSystem details of SystemOverview. | |
| 102 | """ | |
| 103 | doc = Document() | |
| 104 | systemoverview = doc.createElement("systemoverview") | |
| 105 | doc.appendChild(systemoverview) | |
| 106 | for fs in filesystems: | |
| 107 | filesystem = doc.createElement("filesystem") | |
| 108 | filesystem.setAttribute("id", fs[0]) | |
| 109 | systemoverview.appendChild(filesystem) | |
| 110 | size = doc.createElement("size") | |
| 111 | size.appendChild(doc.createTextNode(str(fs[1]))) | |
| 112 | filesystem.appendChild(size) | |
| 113 | used = doc.createElement("used") | |
| 114 | used.appendChild(doc.createTextNode(str(fs[2]))) | |
| 115 | filesystem.appendChild(used) | |
| 116 | avail = doc.createElement("avail") | |
| 117 | avail.appendChild(doc.createTextNode(str(fs[3]))) | |
| 118 | filesystem.appendChild(avail) | |
| 119 | capacity = doc.createElement("capacity") | |
| 120 | capacity.appendChild(doc.createTextNode(str(fs[4]))) | |
| 121 | filesystem.appendChild(capacity) | |
| 122 | mountpoint = doc.createElement("mountpoint") | |
| 123 | mountpoint.appendChild(doc.createTextNode(str(fs[5]))) | |
| 124 | filesystem.appendChild(mountpoint) | |
| 125 | return doc.toprettyxml(indent=" ") | |
| 126 | ||
| 127 | def mailSystemOverview(filesystems): | |
| 128 | """ | |
| 129 | E-Mail a complete System Overview in HTML/MIME format. | |
| 130 | ||
| 131 | @type filesystems: array | |
| 132 | @param filesystems: An array of filesystem tuples. | |
| 133 | """ | |
| 134 | PieCharts = filesystemsToPie(filesystems) | |
| 135 | message = """ | |
| 136 | <HTML> | |
| 137 | <BODY> | |
| 138 | """ | |
| 139 | message += filesystemsToHTML(getHumanUnixDriveInfo()) | |
| 140 | message += "<table border=0 cellspacing=0 cellpadding=0>\n<tr><td colspan=3 width=600 height=22 bgcolor=#2F6297 style=color:#FFFFFF;font-weight:bold;font-family:Arial, Helvetica, sans-serif>Mounted on</td>\n</tr>" | |
| 141 | column = 0 | |
| 142 | PieTable = "<tr>" | |
| 143 | for PieChart in PieCharts: | |
| 144 | if column < 3: | |
| 145 | PieTable += "<td><img src=cid:" + os.path.split(PieChart.name)[1] + "></td>" | |
| 146 | column += 1 | |
| 147 | else: | |
| 148 | PieTable += "</tr><tr><td><img src=cid:" + os.path.split(PieChart.name)[1] + "></td>" | |
| 149 | column = 0 | |
| 150 | PieTable += "</tr>" | |
| 151 | message += PieTable | |
| 152 | message += """ | |
| 153 | </table> | |
| 154 | </BODY> | |
| 155 | </HTML> | |
| 156 | """ | |
| 157 | ||
| 158 | # Create the container (outer) email message. | |
| 159 | msg = MIMEMultipart('mixed') | |
| 160 | msg['Subject'] = 'System Overview' | |
| 161 | # me == the sender's email address | |
| 162 | # family = the list of all recipients' email addresses | |
| 163 | msg['From'] = 'Bserver1' | |
| 164 | msg['To'] = 'Alan@Wave2.co.uk' | |
| 165 | msg.preamble = 'System Overview' | |
| 166 | # Guarantees the message ends in a newline | |
| 167 | msg.epilogue = '' | |
| 168 | msg.attach(MIMEText(message,'HTML')) | |
| 169 | #Attach PieCharts | |
| 170 | for PieChart in PieCharts: | |
| 171 | # Open the files in binary mode. Let the MIMEImage class automatically | |
| 172 | # guess the specific image type. | |
| 173 | img = MIMEImage(PieChart.read(),_subtype="png",name=os.path.split(PieChart.name)[1],filename=os.path.split(PieChart.name)[1]) | |
| 174 | img.add_header('Content-ID',"<" + os.path.split(PieChart.name)[1] + ">") | |
| 175 | msg.attach(img) | |
| 176 | # Send the email via our own SMTP server. | |
| 177 | s = smtplib.SMTP() | |
| 178 | s.connect() | |
| 179 | s.sendmail('Bserver1', 'Alan@Wave2.co.uk', msg.as_string()) | |
| 180 | s.close() | |
| 181 | ||
| 182 | #mailSystemOverview(getUnixDriveInfo()) | |
| 183 | print filesystemsToXML(getHumanUnixDriveInfo()) |