diff --git a/ToggleProxy.py b/ToggleProxy.py index 5070552..54c4804 100644 --- a/ToggleProxy.py +++ b/ToggleProxy.py @@ -3,7 +3,7 @@ from Foundation import * from AppKit import * from SystemConfiguration import * -import commands, re, time +import commands, re class ToggleProxy(NSObject): @@ -15,10 +15,33 @@ class ToggleProxy(NSObject): # make status bar item self.statusitem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength) self.statusitem.retain() - self.statusitem.setAction_("toggleProxy:") - self.statusitem.setTarget_(self) +# self.statusitem.setTarget_(self) self.statusitem.setHighlightMode_(False) self.statusitem.setEnabled_(True) + self.statusitem.setImage_(self.inactive_image) + + # insert a menu into the status bar item + self.menu = NSMenu.alloc().init() + self.statusitem.setMenu_(self.menu) + + # add items to menu + self.httpMenuItem = self.menu.addItemWithTitle_action_keyEquivalent_( + "HTTP proxy", + "toggleHttpProxy:", + "") + self.httpsMenuItem = self.menu.addItemWithTitle_action_keyEquivalent_( + "HTTPS proxy", + "toggleHttpsProxy:", + "") + self.socksMenuItem = self.menu.addItemWithTitle_action_keyEquivalent_( + "SOCKS proxy", + "toggleSocksProxy:", + "") + self.menu.addItem_(NSMenuItem.separatorItem()) + self.menu.addItemWithTitle_action_keyEquivalent_( + "Quit", + "quitApp:", + "") # open connection to the dynamic (configuration) store self.store = SCDynamicStoreCreate(None, "name.klep.toggleproxy", self.dynamicStoreCallback, None) @@ -37,8 +60,8 @@ class ToggleProxy(NSObject): """ load list of network services """ 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 + for servicename, service, device in re.findall(r'\(\d\)\s*(.*?)(?:\n|\r\n?)\(Hardware Port:\s*(.*?), Device:\s*(.*?)\)', output, re.MULTILINE): + self.services[device] = servicename def watchForProxyChanges(self): """ install a watcher for proxy changes """ @@ -59,35 +82,33 @@ class ToggleProxy(NSObject): # get status for primary interface status = proxydict['__SCOPED__'][self.interface] - self.active = status.get('HTTPEnable', False) and True or False - - # set image - self.statusitem.setImage_( self.active and self.active_image or self.inactive_image ) - - # set tooltip - if self.active: - tooltip = "[%s] proxy active on %s:%s" % ( - self.interface, - proxydict.get('HTTPProxy', '??'), - proxydict.get('HTTPPort', '??'), - ) - else: - tooltip = "[%s] proxy not active" % self.interface - self.statusitem.setToolTip_(tooltip) - - def toggleProxy_(self, sender): - """ callback for clicks on menu item """ - # Ctrl pressed? if so, quit - if NSApp.currentEvent().modifierFlags() & NSControlKeyMask: - NSApp.terminate_(self) - return + # update menu items according to their related proxy state + self.httpMenuItem.setState_( status.get('HTTPEnable', False) and NSOnState or NSOffState ) + self.httpsMenuItem.setState_( status.get('HTTPSEnable', False) and NSOnState or NSOffState ) + self.socksMenuItem.setState_( status.get('SOCKSEnable', False) and NSOnState or NSOffState ) + + def quitApp_(self, sender): + NSApp.terminate_(self) + + def toggleHttpProxy_(self, sender): + self.toggleProxy(self.httpMenuItem, 'webproxy') + + def toggleHttpsProxy_(self, sender): + self.toggleProxy(self.httpsMenuItem, 'securewebproxy') + + def toggleSocksProxy_(self, sender): + self.toggleProxy(self.socksMenuItem, 'socksfirewallproxy') + + def toggleProxy(self, item, target): + """ callback for clicks on menu item """ servicename = self.services.get(self.interface) if not servicename: NSLog("interface '%s' not found in services?" % self.interface) return - newstate = self.active and "off" or "on" - commands.getoutput("/usr/sbin/networksetup setwebproxystate %s %s" % ( + newstate = item.state() == NSOffState and 'on' or 'off' + commands.getoutput("/usr/sbin/networksetup -set%sstate '%s' %s" % ( + target, servicename, newstate ))