PySnarl を使ってみる
SnarlというGrowl の Windows 版とでもいうようなソフトがあるのだが、PySnarlという、Snarl の Python binding を見つけたので、以前書いたネットワークの接続状況をシステムトレイに表示するスクリプトに組み込んでみた。
10秒ごとにチェックし、ネットワークが切断されてたり、接続されたりしたタイミングで Snarl を使って Notiy する。なかなか良い。
ちなみに Python Win32 Extension, wxPython, dnspython が必要。
#!/usr/bin/env python import wx import dns.resolver import sys from PySnarl import SnarlMessage ID_ICON_TIMER = wx.NewId() INTERVAL = 10000 # in msec DNS_TIMEOUT = 5 # in sec class MyTaskBarIcon(wx.TaskBarIcon): def __init__(self, frame): wx.TaskBarIcon.__init__(self) self.frame = frame def CreatePopupMenu(self): return self._create_menu() def OnClose(self, _): self.frame.Close(1) def _create_menu(self): menu = wx.Menu() id = wx.NewId() menu.Append(id, "Exit") wx.EVT_MENU(self, id, self.OnClose) return menu class TaskBarApp(wx.Frame): def __init__(self, parent, id, title): style = wx.FRAME_NO_TASKBAR | wx.NO_FULL_REPAINT_ON_RESIZE wx.Frame.__init__(self, parent, -1, title, size = (1, 1), style = style) self.Bind(wx.EVT_CLOSE, self.OnClose) self.timer = wx.Timer(self, ID_ICON_TIMER) self.Bind(wx.EVT_TIMER, self.CheckConnection, self.timer, ID_ICON_TIMER) self.timer.Start(INTERVAL) self.resolver = dns.resolver.get_default_resolver() self.resolver.lifetime = DNS_TIMEOUT self.tbicon = MyTaskBarIcon(self) self.is_connected = False self.snarl = None self.Show(True) self.CheckConnection(None) def CheckConnection(self, _): image = wx.EmptyImage(16, 16) text = 'Network ' try: self.resolver.query("www.google.com") image.SetData('\x11\xff\x11' * 256) text += 'Connected' is_connected = True except dns.resolver.Timeout: image.SetData('\xff\x11\x11' * 256) text += 'Disconnected' is_connected = False bmp = image.ConvertToBitmap() bmp.SetMask(wx.Mask(bmp, wx.WHITE)) icon = wx.EmptyIcon() icon.CopyFromBitmap(bmp) self.tbicon.SetIcon(icon, text) if is_connected != self.is_connected: if self.snarl is not None: self.snarl.hide() self.snarl = SnarlMessage(text) self.snarl.show() self.is_connected = is_connected def OnClose(self, _): self.tbicon.Destroy() self.Destroy() class MyApp(wx.App): def OnInit(self): frame = TaskBarApp(None, -1, ' ') frame.Center(wx.BOTH) frame.Show(False) return True def main(argv=None): if argv is None: argv = sys.argv app = MyApp(0) app.MainLoop() if __name__ == '__main__': main()