{"id":456,"date":"2014-01-11T14:20:59","date_gmt":"2014-01-11T21:20:59","guid":{"rendered":"http:\/\/somethingk.com\/main\/?p=456"},"modified":"2014-01-26T19:46:52","modified_gmt":"2014-01-27T02:46:52","slug":"improvements-detecting-new-network-devices-with-python-and-tkinter","status":"publish","type":"post","link":"https:\/\/somethingk.com\/main\/improvements-detecting-new-network-devices-with-python-and-tkinter\/","title":{"rendered":"IMPROVEMENTS: Detecting New Network Devices with Python and Tkinter"},"content":{"rendered":"<p>So I wasn&#8217;t too happy with the\u00a0kludginess of the network monitoring tool that I <a title=\"Detecting New Network Devices with Python and Tkinter\" href=\"http:\/\/somethingk.com\/main\/?p=375\">posted<\/a> about earlier this week. It lagged and really wasn&#8217;t an ideal tool. I decided to redesign the entire model.<\/p>\n<p><a href=\"http:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-2.58.14-PM.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-457\" alt=\"New Model\" src=\"http:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-2.58.14-PM-300x151.png\" width=\"300\" height=\"151\" srcset=\"https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-2.58.14-PM-300x151.png 300w, https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-2.58.14-PM.png 642w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The new tool still utilizes Python 2.7 and consists of three parts:<\/p>\n<ul>\n<li>Ping\/Enumeration Script<\/li>\n<li>RESTful Django Script<\/li>\n<li>Tkinter Reporting GUI Script<\/li>\n<\/ul>\n<p>Here is how they connect. The Ping\/Enumeration Script, pings all devices given within a network range. Whenever it finds a new device, it runs a NMAP scan on the device then formulates a request to the server to notify it of the device scan results. The script will also notify the server when a device disconnects from the network (this was an issue with the old version).<\/p>\n<p>The Django server manages a sqlite database containing scan results on all devices currently connected to the network. It will remove or add a device record based on the ping script&#8217;s RESTful HTTP request. The server can also return a list of all devices detected. This list is used by the GUI script.<\/p>\n<p>The GUI script maintains a Tkinter dialog window that will circulate through all network connected device scan results. It first sends a GET request to the Django server asking for a JSON list of all connected devices. The script will then display each record found in the JSON. Each device record will appear in the GUI window for 20 seconds. After it has made the rounds through each item, it will make another call to the server for a fresh JSON to iterate through.<\/p>\n<p>The Ping\/Enumeration Script is basically the same as what I discussed earlier. The difference is, after data is collected, it is sent to the Django server in a POST request.<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<td><code><br \/>\nimport commands, re, json, urllib2, binascii<br \/>\nPREFIX = \"192.168.1\" #Network prefix<br \/>\nMIN = \"0\" #Starting network address, eg 192.168.1.0<br \/>\nMAX = \"12\" #Closing network address, e.g. 192.168.1.55<br \/>\nresults = []<\/p>\n<p>def escapeMe(message): #Escape characters (using ASCII value) not allowed in JSON<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;new = \"\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;for num in range(len(message)):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char_code = ord(message[num])<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if char_code &lt; 32 or char_code == 39 or &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char_code == 34 or char_code == 92:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new = new + \"%\" + binascii.hexlify(message[num])<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new = new + message[num]<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return new<\/p>\n<p>def sendDevice(gotcha): #Send the device report to the server as a POST<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url = \"http:\/\/127.0.0.1:3707\/new\/\" #Server address<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gotcha = escapeMe(gotcha)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values = json.dumps({'device' : str(gotcha)})<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req = urllib2.Request(url)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.add_header('Content-Type', 'application\/json')<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rsp = urllib2.urlopen(req, values)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = rsp.getcode()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print e<\/p>\n<p>def removeDevice(ip): #Send request to remove device<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip = ip.replace('.','-')<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url = \"http:\/\/127.0.0.1:3707\/remove\/\"+ip+\"\/\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rsp = urllib2.urlopen(url)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = rsp.getcode()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print e<\/p>\n<p>def main():<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;global results<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;while 1:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new = commands.getoutput('for i in {'+MIN+'..'+MAX+'}; do ping -c 1 -t 1 '+PREFIX+'.$i | grep \"from\"; done') #Ping sweep the network to find connected devices<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = re.findall(PREFIX+\"\\.(\\d+)\", str(new)) #Pull out IP addresses from the ping results<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if tmp != results:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ip in tmp:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ip not in results:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gotcha = commands.getoutput('nmap -v -A -Pn '+PREFIX+'.'+ip) #nmap new devices found on the network<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sendDevice(gotcha) #send device record to server<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for r in results:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if r not in tmp:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeDevice(PREFIX+'.'+r) #remove device if it wasn't found in the latest ping<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;results = tmp<\/p>\n<p>if __name__ == \"__main__\":<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;main()<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a title=\"Django\" href=\"https:\/\/www.djangoproject.com\" target=\"_blank\">Django<\/a> is an awesome Python Web Application Framework that I absolutely adore (not the movie \ud83d\ude42 ). It is known as the web framework for perfectionists with deadlines. Most of my web projects utilize Django.<\/p>\n<p><a href=\"http:\/\/www.imdb.com\/title\/tt1853728\/\"><img fetchpriority=\"high\" decoding=\"async\" src=\"http:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/django-202x300.jpg\" alt=\"Django\" width=\"202\" height=\"300\" class=\"aligncenter size-medium wp-image-575\" srcset=\"https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/django-202x300.jpg 202w, https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/django.jpg 486w\" sizes=\"(max-width: 202px) 100vw, 202px\" \/><\/a><\/p>\n<p>It comes with its own lightweight server to host its applications, so its perfect for any development environment. For the sake of this project, I&#8217;m using its server, all script\/server functionality is limited to the host machine running the tool. Everything is internal. Django also handles the RESTful routing and database modeling. It uses the model view controller (<a title=\"Model-View-Controller\" href=\"http:\/\/en.wikipedia.org\/wiki\/Model\u2013view\u2013controller\" target=\"_blank\">MVC<\/a>) structure. Here is a great <a title=\"Writing your first Django App\" href=\"https:\/\/docs.djangoproject.com\/en\/dev\/intro\/tutorial01\/\" target=\"_blank\">tutorial<\/a> on how to create your own Django app, definitely worth looking into!<\/p>\n<p>The following is the break down of code I wrote for the Django server (running version 1.3).<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<td><code><br \/>\n####################models.py####################<br \/>\nfrom django.db import models<\/p>\n<p>class Devices(models.Model):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;device = models.TextField()<\/p>\n<p>####################ADD to urls.py####################<br \/>\nurl(r'^new\/$', 'lilDevil.views.new', name='new'),<br \/>\nurl(r'^listDevices\/$', 'lilDevil.views.listDevices', name='listDevices'),<br \/>\nurl(r'^remove\/(?P*ip*.+)\/$', 'lilDevil.views.remove', name='remove'), #REPLACE * with greater\/less sign containing brackets<\/p>\n<p>####################views.py####################<br \/>\nfrom django.http import HttpResponse<br \/>\nfrom lilDevil.models import Devices<br \/>\nimport json<\/p>\n<p>def remove(request, ip):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip = ip.replace('-','.')<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;devicelist = Devices.objects.all()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for d in devicelist:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ip in d.device:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d.delete()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return HttpResponse(status = 200)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return HttpResponse(e)<\/p>\n<p>def new(request):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encoded = json.loads(request.raw_post_data)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new = Devices(device=encoded[\"device\"])<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new.save()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return HttpResponse(status = 200)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return HttpResponse(e)<\/p>\n<p>def listDevices(request):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;json_string = '{\"devices\": ['<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;devicelist = Devices.objects.all()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first = True<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for d in devicelist:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if first:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first = False<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;json_string = json_string + ', '<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;json_string = json_string + '{\"device\": \"'+str(d.device)+'\"}'<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;json_string = json_string + ']}'<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return HttpResponse(json_string)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print HttpResponse(e)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Finally, the GUI script. Very similar to the one in the old post. Again, I just added the ability to request device data from the server.<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<td><code><br \/>\nfrom Tkinter import *<br \/>\nimport time, urllib2, urllib, json<br \/>\nclass flipGUI(Tk):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;def __init__(self,*args, **kwargs): #Setup the GUI and make it pretty<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tk.__init__(self, *args, **kwargs)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1 = Label(self, width= 65, justify=CENTER, padx=5, pady=5, text=\"Guests\") #Text label<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label2 = Label(self, text=\"\") #Photo label<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label2.grid(row=0, column=1, sticky=W+E+N+S, padx=5, pady=5)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1.grid(row=0, column=0)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.flipping()<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;def flipping(self): #Flip through NMAP scans of detected devices<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = self.label1.cget(\"text\")<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = self.label2.cget(\"image\")<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = getData()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found = json.loads(data)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;photo = PhotoImage(file=\"picture.gif\")<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if found['devices']:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for f in found['devices']: #Loop through all but the last item<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fixed = f['device'].replace('%0a', '\\n') #return to ASCII value from earlier escaped hex<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1.config(text=fixed)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1.update()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label2.config(image=photo)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label2.update()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(20)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1.config(text=\"No connected devices\")<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.label1.update()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(20)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.after(1, self.flipping())<\/p>\n<p>def getData(): #Get a list of devices from server<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;url = \"http:\/\/127.0.0.1:3707\/listDevices\/\" #server address<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;response = urllib2.urlopen(url)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;code = response.getcode()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;if int(code) == 200:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return response.read()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;else:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<\/p>\n<p>if __name__ == \"__main__\":<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;try:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while 1:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app = flipGUI()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.mainloop()<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;except Exception, e:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print e<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Final Note:<\/strong> Make sure to delete\/clear out database or old results will carry over! I did this in an <a href=\"http:\/\/somethingk.com\/main\/?p=705\" title=\"Init.d Scripts\">init.d<\/a> script that calls the service.<\/p>\n<p>Put it all together and you have a much more stable tool. I renamed it from the Hindenburg to the Lil Devil.<\/p>\n<figure id=\"attachment_463\" aria-describedby=\"caption-attachment-463\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-3.49.53-PM.png\"><img decoding=\"async\" class=\"size-medium wp-image-463\" alt=\"The Lil Devil\" src=\"http:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-3.49.53-PM-300x214.png\" width=\"300\" height=\"214\" srcset=\"https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-3.49.53-PM-300x214.png 300w, https:\/\/somethingk.com\/main\/wp-content\/uploads\/2014\/01\/Screen-Shot-2014-01-11-at-3.49.53-PM.png 808w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-463\" class=\"wp-caption-text\">The Lil Devil<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>So I wasn&#8217;t too happy with the\u00a0kludginess of the network monitoring tool that I posted about earlier this week. It lagged and really wasn&#8217;t an ideal tool. I decided to redesign the entire model. The new tool still utilizes Python 2.7 and consists of three parts: Ping\/Enumeration Script RESTful Django Script Tkinter Reporting GUI Script Here is how they connect. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,39,93,72,38],"tags":[104,118,146,115,17,153,117,105,116],"class_list":["post-456","post","type-post","status-publish","format-standard","hentry","category-enumeration","category-fingerprinting","category-networking","category-python","category-vulnerability-scanner","tag-devices","tag-django","tag-django-1-3","tag-improvements","tag-ping","tag-python-2-7","tag-restful","tag-tkinter","tag-upgrade"],"_links":{"self":[{"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/posts\/456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/comments?post=456"}],"version-history":[{"count":25,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/posts\/456\/revisions"}],"predecessor-version":[{"id":1084,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/posts\/456\/revisions\/1084"}],"wp:attachment":[{"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/media?parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/categories?post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/somethingk.com\/main\/wp-json\/wp\/v2\/tags?post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}