Mac OS X menu item for quickly enabling/disabling HTTP proxy
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

86 lignes
3.3 KiB

  1. #!/usr/bin/env python
  2. from Foundation import *
  3. from AppKit import *
  4. from SystemConfiguration import *
  5. import commands, re, time
  6. class ProxySwitcher(NSObject):
  7. def applicationDidFinishLaunching_(self, notification):
  8. # make status bar item
  9. self.statusitem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
  10. self.statusitem.retain()
  11. self.statusitem.setAction_("toggleProxy:")
  12. self.statusitem.setTarget_(self)
  13. self.statusitem.setHighlightMode_(False)
  14. self.statusitem.setEnabled_(True)
  15. # define some title-related stuff
  16. self.active_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0, 0.5, 0, 1)
  17. self.inactive_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0.6, 0, 0, 1)
  18. self.title_font = NSFont.fontWithName_size_('HelveticaNeue-Bold', 12.0)
  19. # start working
  20. self.loadNetworkServices()
  21. self.watchForProxyChanges()
  22. self.updateProxyStatus()
  23. def loadNetworkServices(self):
  24. self.services = {}
  25. output = commands.getoutput("/usr/sbin/networksetup listnetworkserviceorder")
  26. for service, device in re.findall(r'Hardware Port:\s*(.*?), Device:\s*(.*?)\)', output):
  27. self.services[device] = service
  28. def watchForProxyChanges(self):
  29. store = SCDynamicStoreCreate(None, "name.klep.proxyswitcher", self.proxyStateChanged, None)
  30. SCDynamicStoreSetNotificationKeys(store, None, [ 'State:/Network/Global/Proxies' ])
  31. source = SCDynamicStoreCreateRunLoopSource(None, store, 0)
  32. loop = NSRunLoop.currentRunLoop().getCFRunLoop()
  33. CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes)
  34. def proxyStateChanged(self, store, keys, info):
  35. self.updateProxyStatus()
  36. def updateProxyStatus(self):
  37. proxydict = SCDynamicStoreCopyProxies(None)
  38. interface = proxydict['__SCOPED__'].keys()[0]
  39. status = proxydict['__SCOPED__'][interface]
  40. self.active = status.get('HTTPEnable', False) and True or False
  41. self.device = interface
  42. title = NSAttributedString.alloc().initWithString_attributes_(
  43. "Proxy %sactive" % (not self.active and "in" or ""), {
  44. # NSFontAttributeName : self.title_font,
  45. NSForegroundColorAttributeName : self.active and self.active_color or self.inactive_color,
  46. }
  47. )
  48. self.statusitem.setAttributedTitle_(title)
  49. if self.active:
  50. tooltip = "Proxy active on %s:%s" % (
  51. proxydict.get('HTTPProxy', '??'),
  52. proxydict.get('HTTPPort', '??')
  53. )
  54. else:
  55. tooltip = ""
  56. self.statusitem.setToolTip_(tooltip)
  57. def toggleProxy_(self, sender):
  58. servicename = self.services.get(self.device)
  59. if not servicename:
  60. NSLog("device '%s' not found in services?" % self.device)
  61. return
  62. newstate = self.active and "off" or "on"
  63. commands.getoutput("networksetup setwebproxystate %s %s" % (
  64. servicename,
  65. newstate
  66. ))
  67. self.updateProxyStatus()
  68. if __name__ == '__main__':
  69. sharedapp = NSApplication.sharedApplication()
  70. switcher = ProxySwitcher.alloc().init()
  71. sharedapp.setDelegate_(switcher)
  72. sharedapp.run()