|
|
@@ -3,10 +3,19 @@ |
|
|
|
from Foundation import * |
|
|
|
from AppKit import * |
|
|
|
from SystemConfiguration import * |
|
|
|
# from pprint import pprint |
|
|
|
import commands, re |
|
|
|
|
|
|
|
class ToggleProxy(NSObject): |
|
|
|
|
|
|
|
proxies = { |
|
|
|
'ftp' : { 'pref': kSCPropNetProxiesFTPEnable, 'title': 'FTP Proxy', 'action': 'toggleFtpProxy:', 'keyEquivalent': "", 'menuitem': None }, |
|
|
|
'http' : { 'pref': kSCPropNetProxiesHTTPEnable, 'title': 'HTTP Proxy', 'action': 'toggleHttpProxy:', 'keyEquivalent': "", 'menuitem': None }, |
|
|
|
'https': { 'pref': kSCPropNetProxiesHTTPSEnable, 'title': 'HTTPS Proxy', 'action': 'toggleHttpsProxy:', 'keyEquivalent': "", 'menuitem': None }, |
|
|
|
'rtsp': { 'pref': kSCPropNetProxiesRTSPEnable, 'title': 'RTSP Proxy', 'action': 'toggleRtspProxy:', 'keyEquivalent': "", 'menuitem': None }, |
|
|
|
'socks': { 'pref': kSCPropNetProxiesSOCKSEnable, 'title': 'SOCKS Proxy', 'action': 'toggleSocksProxy:', 'keyEquivalent': "", 'menuitem': None }, |
|
|
|
} |
|
|
|
|
|
|
|
def applicationDidFinishLaunching_(self, notification): |
|
|
|
# load icon files |
|
|
|
self.icons = { |
|
|
@@ -30,28 +39,40 @@ class ToggleProxy(NSObject): |
|
|
|
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()) |
|
|
|
# open connection to the dynamic (configuration) store |
|
|
|
self.store = SCDynamicStoreCreate(None, "name.klep.toggleproxy", self.dynamicStoreCallback, None) |
|
|
|
|
|
|
|
service = self.service |
|
|
|
|
|
|
|
proxyRef = SCNetworkServiceCopyProtocol(service, kSCNetworkProtocolTypeProxies) |
|
|
|
prefDict = SCNetworkProtocolGetConfiguration(proxyRef) |
|
|
|
# pprint(prefDict) |
|
|
|
|
|
|
|
separatorRequired = False |
|
|
|
|
|
|
|
for proxy in self.proxies.values(): |
|
|
|
enabled = CFDictionaryGetValue(prefDict, proxy['pref']) |
|
|
|
if enabled is not None: |
|
|
|
proxy['menuitem'] = self.menu.addItemWithTitle_action_keyEquivalent_( |
|
|
|
proxy['title'], |
|
|
|
proxy['action'], |
|
|
|
proxy['keyEquivalent'] |
|
|
|
) |
|
|
|
separatorRequired = True |
|
|
|
else: |
|
|
|
# NSLog("%s does not appear to be configured" % proxy['title']) |
|
|
|
proxy['menuitem'] = None |
|
|
|
|
|
|
|
# pprint(self.proxies) |
|
|
|
|
|
|
|
if separatorRequired: |
|
|
|
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) |
|
|
|
|
|
|
|
# start working |
|
|
|
self.loadNetworkServices() |
|
|
|
self.watchForProxyChanges() |
|
|
@@ -62,6 +83,19 @@ class ToggleProxy(NSObject): |
|
|
|
# get primary interface |
|
|
|
return SCDynamicStoreCopyValue(self.store, 'State:/Network/Global/IPv4')['PrimaryInterface'] |
|
|
|
|
|
|
|
@property |
|
|
|
def service(self): |
|
|
|
""" Returns the service relating to self.interface """ |
|
|
|
prefs = SCPreferencesCreate(kCFAllocatorDefault, 'PRG', None) |
|
|
|
|
|
|
|
# Fetch the list of services |
|
|
|
for serviceRef in SCNetworkServiceCopyAll(prefs): |
|
|
|
interface = SCNetworkServiceGetInterface(serviceRef) |
|
|
|
bsdname = SCNetworkInterfaceGetBSDName(interface) |
|
|
|
if self.interface == bsdname: |
|
|
|
return serviceRef |
|
|
|
return None |
|
|
|
|
|
|
|
def loadNetworkServices(self): |
|
|
|
""" Load and store a list of network services indexed by their BSDName """ |
|
|
|
self.services = {} |
|
|
@@ -92,36 +126,42 @@ class ToggleProxy(NSObject): |
|
|
|
def updateProxyStatus(self): |
|
|
|
""" update proxy status """ |
|
|
|
# load proxy dictionary |
|
|
|
proxydict = SCDynamicStoreCopyProxies(None) |
|
|
|
proxydict = SCDynamicStoreCopyProxies(None) |
|
|
|
|
|
|
|
# get status for primary interface |
|
|
|
status = proxydict['__SCOPED__'][self.interface] |
|
|
|
status = proxydict['__SCOPED__'][self.interface] |
|
|
|
|
|
|
|
# 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 ) |
|
|
|
for proxy in self.proxies.values(): |
|
|
|
if proxy['menuitem']: |
|
|
|
proxy['menuitem'].setState_( status.get(proxy['pref'], False) and NSOnState or NSOffState) |
|
|
|
|
|
|
|
# update icon |
|
|
|
self.statusitem.setImage_( |
|
|
|
self.icons['%d-%d-%d' % ( |
|
|
|
status.get('HTTPEnable', False) and 1 or 0, |
|
|
|
status.get('HTTPSEnable', False) and 1 or 0, |
|
|
|
status.get('SOCKSEnable', False) and 1 or 0 |
|
|
|
status.get(self.proxies['http']['pref'], False) and 1 or 0, |
|
|
|
status.get(self.proxies['https']['pref'], False) and 1 or 0, |
|
|
|
status.get(self.proxies['socks']['pref'], False) and 1 or 0 |
|
|
|
)] |
|
|
|
) |
|
|
|
|
|
|
|
def quitApp_(self, sender): |
|
|
|
NSApp.terminate_(self) |
|
|
|
|
|
|
|
def toggleFtpProxy_(self, sender): |
|
|
|
self.toggleProxy(self.proxies['ftp']['menuitem'], 'ftpproxy') |
|
|
|
|
|
|
|
def toggleHttpProxy_(self, sender): |
|
|
|
self.toggleProxy(self.httpMenuItem, 'webproxy') |
|
|
|
self.toggleProxy(self.proxies['http']['menuitem'], 'webproxy') |
|
|
|
|
|
|
|
def toggleHttpsProxy_(self, sender): |
|
|
|
self.toggleProxy(self.httpsMenuItem, 'securewebproxy') |
|
|
|
self.toggleProxy(self.proxies['https']['menuitem'], 'securewebproxy') |
|
|
|
|
|
|
|
def toggleRtspProxy_(self, sender): |
|
|
|
self.toggleProxy(self.proxies['socks']['menuitem'], 'streamingproxy') |
|
|
|
|
|
|
|
def toggleSocksProxy_(self, sender): |
|
|
|
self.toggleProxy(self.socksMenuItem, 'socksfirewallproxy') |
|
|
|
self.toggleProxy(self.proxies['socks']['menuitem'], 'socksfirewallproxy') |
|
|
|
|
|
|
|
def toggleProxy(self, item, target): |
|
|
|
""" callback for clicks on menu item """ |
|
|
|