| @@ -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 | |||
| )) | |||