portcheck.py
python/portcheck.py download
import pygtk
pygtk.require('2.0')
import gtk
import socket
import sys
import pynotify
def check_port(host, port):
socket.setdefaulttimeout(2.0)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host, port))
s.shutdown(2)
return True
except:
return False
# list to check; url:port, active - is this record used?, success - result of the last check
# the optional string 'alias' defines the name to show in the menu instead of url:port
sites = [{'url': 'localhost', 'port': 80, 'alias': 'localhost', 'active': True, 'success': None}]
# how often should we check, in sec
check_every = 30.0
class PortsCheckerTray:
def __init__(self):
if not pynotify.init("Ports checker"):
sys.exit(1)
self.statusIcon = gtk.StatusIcon()
self.menu = gtk.Menu()
self.last_result = None
self.check_ports_cb()
self.statusIcon.connect('popup-menu', self.popup_menu_cb, self.menu)
self.statusIcon.set_visible(True)
gtk.main()
def set_icon(self, success):
if success:
self.statusIcon.set_from_stock(gtk.STOCK_APPLY)
else:
self.statusIcon.set_from_stock(gtk.STOCK_STOP)
# count up/down numbers
up_cnt = 0
down_cnt = 0
for d in sites:
if not d['active']:
continue
if d['success']:
up_cnt = up_cnt + 1
else:
down_cnt = down_cnt + 1
self.statusIcon.set_visible(True)
self.statusIcon.set_tooltip("Ports checker [" + str(up_cnt) + " up, " + str(down_cnt) + " down]")
def get_name(self, site_dict):
if 'alias' in site_dict:
return site_dict['alias']
else:
return site_dict['url'] + ":" + str(site_dict['port'])
def populate_menu(self):
for mi in self.menu.get_children(): # just remove all items from menu, repopulate from scratch
self.menu.remove(mi)
for d in sites:
if d['active'] != True:
continue
name = self.get_name(d)
if d['success']:
self.menuItem = gtk.MenuItem("up: " + name)
else:
self.menuItem = gtk.MenuItem("DOWN: " + name)
self.menu.append(self.menuItem)
self.menuItem.show()
self.menuItem = gtk.SeparatorMenuItem()
self.menu.append(self.menuItem)
self.menuItem.show()
self.menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
self.menuItem.connect('activate', self.quit_cb, self.statusIcon)
self.menu.append(self.menuItem)
def notify_about(self, changed):
nots = []
for d in changed:
if d['success']:
msg = self.get_name(d) + " is online."
else:
msg = self.get_name(d) + " is OFFLINE."
nots.append(msg)
n = pynotify.Notification("Ports checker", "\n".join(nots))
return n.show()
def check_ports_cb(self):
global sites
#for d in sites:
# print d
changed = []
all_passed = True
for d in sites:
if d['active'] != True:
continue
ret = check_port(d['url'], d['port'])
if d['success'] != ret:
d['success'] = ret
changed.append(d)
if ret == False:
all_passed = False
# create list of checked sites in the menu, based on the results
if changed != []:
self.populate_menu()
self.notify_about(changed)
# update the status icon if the overall result changed
if self.last_result != all_passed:
self.set_icon(all_passed)
self.last_result = all_passed
self.statusIcon.connect('popup-menu', self.popup_menu_cb, self.menu)
self.statusIcon.set_visible(True)
# we're ready for another round of checks in 5 secs
global check_every
gtk.timeout_add(int(check_every * 1000), self.check_ports_cb)
def quit_cb(self, widget, data = None):
gtk.main_quit()
def popup_menu_cb(self, widget, button, time, data = None):
if button == 3:
if data:
data.show_all()
data.popup(None, None, gtk.status_icon_position_menu,
3, time, self.statusIcon)
if __name__ == "__main__":
portsChecker = PortsCheckerTray()