| @@ -3,7 +3,7 @@ | |||||
| from Foundation import * | from Foundation import * | ||||
| from AppKit import * | from AppKit import * | ||||
| from SystemConfiguration import * | from SystemConfiguration import * | ||||
| import commands, re, time | |||||
| import commands, re | |||||
| class ToggleProxy(NSObject): | class ToggleProxy(NSObject): | ||||
| @@ -15,10 +15,33 @@ class ToggleProxy(NSObject): | |||||
| # make status bar item | # make status bar item | ||||
| self.statusitem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength) | self.statusitem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength) | ||||
| self.statusitem.retain() | self.statusitem.retain() | ||||
| self.statusitem.setAction_("toggleProxy:") | |||||
| self.statusitem.setTarget_(self) | |||||
| # self.statusitem.setTarget_(self) | |||||
| self.statusitem.setHighlightMode_(False) | self.statusitem.setHighlightMode_(False) | ||||
| self.statusitem.setEnabled_(True) | 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 | # open connection to the dynamic (configuration) store | ||||
| self.store = SCDynamicStoreCreate(None, "name.klep.toggleproxy", self.dynamicStoreCallback, None) | self.store = SCDynamicStoreCreate(None, "name.klep.toggleproxy", self.dynamicStoreCallback, None) | ||||
| @@ -37,8 +60,8 @@ class ToggleProxy(NSObject): | |||||
| """ load list of network services """ | """ load list of network services """ | ||||
| self.services = {} | self.services = {} | ||||
| output = commands.getoutput("/usr/sbin/networksetup listnetworkserviceorder") | 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): | def watchForProxyChanges(self): | ||||
| """ install a watcher for proxy changes """ | """ install a watcher for proxy changes """ | ||||
| @@ -59,35 +82,33 @@ class ToggleProxy(NSObject): | |||||
| # get status for primary interface | # get status for primary interface | ||||
| status = proxydict['__SCOPED__'][self.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) | servicename = self.services.get(self.interface) | ||||
| if not servicename: | if not servicename: | ||||
| NSLog("interface '%s' not found in services?" % self.interface) | NSLog("interface '%s' not found in services?" % self.interface) | ||||
| return | 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, | servicename, | ||||
| newstate | newstate | ||||
| )) | )) | ||||