Browse Source

Menu dynamically shows only those proxies which are configured. Support for FTP and RTSP proxies.

Signed-off-by: Martin Koistinen <mkoistinen@gmail.com>
tags/v1.0.0
Martin Koistinen 8 years ago
parent
commit
05aac311a5
1 changed files with 68 additions and 28 deletions
  1. +68
    -28
      ToggleProxy.py

+ 68
- 28
ToggleProxy.py View File

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


Loading…
Cancel
Save