commit 9113abe2f374e492ee4b5baf306f1aa6c00734d1 Author: Robert Klep Date: Fri Nov 11 18:37:19 2011 +0100 Initial import diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..6c328b2 --- /dev/null +++ b/.hgignore @@ -0,0 +1,4 @@ +syntax: glob + +dist/* +build/* diff --git a/ProxySwitcher.py b/ProxySwitcher.py new file mode 100644 index 0000000..8fca5a9 --- /dev/null +++ b/ProxySwitcher.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +from Foundation import * +from AppKit import * +from SystemConfiguration import * +import commands, re, time + +class ProxySwitcher(NSObject): + + def applicationDidFinishLaunching_(self, notification): + # make status bar item + self.statusitem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength) + self.statusitem.retain() + self.statusitem.setAction_("toggleProxy:") + self.statusitem.setTarget_(self) + self.statusitem.setHighlightMode_(False) + self.statusitem.setEnabled_(True) + + # define some title-related stuff + self.active_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0, 0.5, 0, 1) + self.inactive_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0.6, 0, 0, 1) + self.title_font = NSFont.fontWithName_size_('HelveticaNeue-Bold', 12.0) + + # start working + self.loadNetworkServices() + self.watchForProxyChanges() + self.updateProxyStatus() + + def loadNetworkServices(self): + self.services = {} + output = commands.getoutput("/usr/sbin/networksetup listnetworkserviceorder") + for service, device in re.findall(r'Hardware Port:\s*(.*?), Device:\s*(.*?)\)', output): + self.services[device] = service + + def watchForProxyChanges(self): + store = SCDynamicStoreCreate(None, "name.klep.proxyswitcher", self.proxyStateChanged, None) + SCDynamicStoreSetNotificationKeys(store, None, [ 'State:/Network/Global/Proxies' ]) + + source = SCDynamicStoreCreateRunLoopSource(None, store, 0) + loop = NSRunLoop.currentRunLoop().getCFRunLoop() + CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes) + + def proxyStateChanged(self, store, keys, info): + self.updateProxyStatus() + + def updateProxyStatus(self): + proxydict = SCDynamicStoreCopyProxies(None) + interface = proxydict['__SCOPED__'].keys()[0] + status = proxydict['__SCOPED__'][interface] + self.active = status.get('HTTPEnable', False) and True or False + self.device = interface + + title = NSAttributedString.alloc().initWithString_attributes_( + "Proxy %sactive" % (not self.active and "in" or ""), { + # NSFontAttributeName : self.title_font, + NSForegroundColorAttributeName : self.active and self.active_color or self.inactive_color, + } + ) + self.statusitem.setAttributedTitle_(title) + if self.active: + tooltip = "Proxy active on %s:%s" % ( + proxydict.get('HTTPProxy', '??'), + proxydict.get('HTTPPort', '??') + ) + else: + tooltip = "" + self.statusitem.setToolTip_(tooltip) + + def toggleProxy_(self, sender): + servicename = self.services.get(self.device) + if not servicename: + NSLog("device '%s' not found in services?" % self.device) + return + newstate = self.active and "off" or "on" + commands.getoutput("networksetup setwebproxystate %s %s" % ( + servicename, + newstate + )) + self.updateProxyStatus() + +if __name__ == '__main__': + sharedapp = NSApplication.sharedApplication() + switcher = ProxySwitcher.alloc().init() + sharedapp.setDelegate_(switcher) + sharedapp.run() diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..250175c --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +from distutils.core import setup +from glob import glob +import py2app, sys, os, commands + +# define distutils setup structure +setup( + app = [ 'ProxySwitcher.py' ], + options = dict(py2app = dict( + plist = dict( + LSBackgroundOnly = True + ) + )) +)