-
Notifications
You must be signed in to change notification settings - Fork 873
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a1fc12a
Showing
114 changed files
with
48,196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Copyright (c) 2014, [email protected] | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Firefly Python 版本已不再维护 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"title": "Firefly Proxy", | ||
"icon": "firefly.icns", | ||
"background": "bkg.png", | ||
"icon-size": 80, | ||
"contents": [ | ||
{ "x": 448, "y": 344, "type": "link", "path": "/Applications" }, | ||
{ "x": 192, "y": 344, "type": "file", "path": "dist/Firefly.app" } | ||
] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import os | ||
|
||
def default_browser(): | ||
import LaunchServices | ||
import CoreData | ||
|
||
brzs = ["safari", "chrome", "firefox"] | ||
|
||
url = CoreData.CFURLRef.URLWithString_("http://www.google.com") | ||
os_status, app_ref, _ = LaunchServices.LSGetApplicationForURL(url, LaunchServices.kLSRolesAll, None, None) | ||
if os_status != 0: | ||
return None | ||
apppath = app_ref.as_pathname() | ||
name = os.path.basename(apppath).lower() | ||
for brz in brzs: | ||
if brz in name: | ||
return brz | ||
return None | ||
|
||
def iterate_browsers(default=None): | ||
default = default_browser() | ||
browsers = [] | ||
if os.path.exists("/Applications/Google Chrome.app"): | ||
browsers.append(( | ||
"chrome", | ||
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", | ||
default=="chrome", | ||
False, | ||
)) | ||
if os.path.exists("/Applications/Firefox.app"): | ||
browsers.append(( | ||
"firefox", | ||
"/Applications/Firefox.app/Contents/MacOS/firefox", | ||
default=="firefox", | ||
False, | ||
)) | ||
# It is not easy to setup proxy programmatically without use authorization. | ||
# | ||
if os.path.exists("/Applications/Safari.app"): | ||
browsers.append(( | ||
"safari", | ||
"open -a Safari", | ||
default=="safari", | ||
False, | ||
)) | ||
return browsers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
# Copied from https://github.com/downloadam/client/blob/master/client/registry/win.py | ||
import logging | ||
import sys | ||
import os | ||
from contextlib import contextmanager | ||
import subprocess | ||
|
||
import _winreg as winreg | ||
from _winreg import HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, \ | ||
KEY_QUERY_VALUE, REG_SZ, KEY_ALL_ACCESS, KEY_WRITE, KEY_CREATE_SUB_KEY, KEY_SET_VALUE | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
@contextmanager | ||
def open_key(hkey, *args): | ||
key = winreg.OpenKeyEx(hkey, *args) | ||
yield key | ||
winreg.CloseKey(key) | ||
|
||
@contextmanager | ||
def create_key(hkey, subkey): | ||
key = winreg.CreateKey(hkey, subkey) | ||
yield key | ||
winreg.CloseKey(key) | ||
|
||
def read_reg_key(hkey, subkey, name=""): | ||
try: | ||
with open_key(hkey, subkey, 0, KEY_QUERY_VALUE) as k: | ||
return winreg.QueryValueEx(k, name) | ||
except WindowsError as e: | ||
errno, message = e.args | ||
if errno != 2: | ||
raise e | ||
return (None, None) | ||
|
||
def write_reg_key(hkey, subkey, name, value): | ||
try: | ||
with open_key(hkey, subkey, 0, KEY_ALL_ACCESS) as k: | ||
winreg.SetValueEx(k, name, 0, value[0], value[1]) | ||
return True | ||
except WindowsError as e: | ||
errno, message = e.args | ||
if errno != 2: | ||
raise e | ||
return False | ||
|
||
def enum_reg_keys(hkey, subkey): | ||
with open_key(hkey, subkey) as k: | ||
i = 0 | ||
while True: | ||
try: | ||
name = winreg.EnumKey(k, i) | ||
except: | ||
break | ||
yield name | ||
i += 1 | ||
|
||
def _parse_browser_path(path): | ||
try: | ||
if path.startswith('"'): | ||
path = path[1:].split('"', 1)[0] | ||
return path | ||
except: | ||
return None | ||
|
||
def get_default_browser(): | ||
result = _parse_browser_path(read_reg_key(HKEY_CURRENT_USER, 'Software\\Classes\\http\\shell\\open\\command')[0]) | ||
if result is None: | ||
result = _parse_browser_path(read_reg_key(HKEY_CLASSES_ROOT, 'http\\shell\\open\\command')[0]) | ||
return result | ||
|
||
def get_browser_path(key): | ||
result = _parse_browser_path(read_reg_key(HKEY_CURRENT_USER, 'Software\\Clients\\StartMenuInternet\\{}\\shell\\open\\command'.format(key))[0]) | ||
if result is None: | ||
result = _parse_browser_path(read_reg_key(HKEY_LOCAL_MACHINE, 'Software\\Clients\\StartMenuInternet\\{}\\shell\\open\\command'.format(key))[0]) | ||
return result | ||
|
||
def iterate_browsers(default=None): | ||
if default is None: | ||
default = get_default_browser() or '' | ||
default = default.lower() | ||
ignore = set() | ||
for hkey in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE): | ||
try: | ||
enum = list(enum_reg_keys(hkey, 'Software\\Clients\\StartMenuInternet')) | ||
except WindowsError: | ||
# key not exists or something? | ||
continue | ||
for key in enum: | ||
if key in ignore: | ||
continue | ||
ignore.add(key) | ||
path = get_browser_path(key) | ||
if not path: | ||
continue | ||
if not os.path.exists(path): | ||
continue | ||
if key == 'IEXPLORE.EXE': | ||
try: | ||
version = int(read_reg_key(hkey, 'Software\\Microsoft\\Internet Explorer', 'Version')[0].split('.', 1)[0]) | ||
except AttributeError: # this maybe happens, don't know why. assume IE is outdated | ||
version = 0 | ||
if version < 9: | ||
outdated = True | ||
else: | ||
outdated = False | ||
elif key == 'OperaStable': | ||
outdated = True | ||
else: | ||
outdated = False | ||
yield key.lower(), path, path.lower() == default, outdated | ||
|
||
old_ie_settings = {} | ||
|
||
def resume_ie_settings(): | ||
global old_ie_settings | ||
key = HKEY_CURRENT_USER | ||
subkey = 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings' | ||
for (name, value) in old_ie_settings.items(): | ||
write_reg_key(key, subkey, name, value) | ||
|
||
def launch_ie(executable, url, rootdir, proxy_type, proxy_ip, proxy_port): | ||
global old_ie_settings | ||
|
||
key = HKEY_CURRENT_USER | ||
subkey = 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings' | ||
new_values = { | ||
'ProxyEnable' : (4, 1), | ||
'ProxyOverride' : (1, u'*.local;<local>'), | ||
'ProxyServer' : (1, u'%s:%d' % (proxy_ip, proxy_port)), | ||
} | ||
for (name, _) in new_values.items(): | ||
(reg_value, reg_type) = read_reg_key(key, subkey, name) | ||
if reg_value is not None: | ||
old_ie_settings[name] = (reg_type, reg_value) | ||
write_reg_key(key, subkey, name, new_values[name]) | ||
cmdline = [ | ||
executable, | ||
url, | ||
] | ||
cmdline = [s.encode(sys.getfilesystemencoding()) for s in cmdline] | ||
return subprocess.Popen(cmdline) | ||
|
||
def launch_ie_tab(executable, url, rootdir): | ||
cmdline = [ | ||
executable, | ||
url, | ||
] | ||
cmdline = [s.encode(sys.getfilesystemencoding()) for s in cmdline] | ||
return subprocess.Popen(cmdline) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from lib.ipc import ActorObject | ||
|
||
class UI(ActorObject): | ||
def __init__(self, coordinator): | ||
super(UI, self).__init__() | ||
self.coordinator = coordinator | ||
|
||
def run(self): | ||
try: | ||
# due to some bugs, the import must goes after Process.start | ||
# see this link: http://stackoverflow.com/questions/21143866/python-tkinter-application-causes-fork-exec-error-on-mac-os-x | ||
self.start_actor() | ||
from component._ui_mac_app import FireflyApp | ||
app = FireflyApp(self.coordinator) | ||
app.run() | ||
self.quit_actor() | ||
except Exception, e: | ||
print e | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# -*- coding: utf-8 -*- | ||
import os | ||
import rumps | ||
|
||
class FireflyApp(rumps.App): | ||
def __init__(self, coordinator): | ||
self.coordinator = coordinator | ||
|
||
rootdir = self.coordinator.get('rootdir') | ||
confdata = self.coordinator.get('confdata') | ||
icon = os.path.join(rootdir, confdata['icon_path']) | ||
super(FireflyApp, self).__init__("Firefly", icon=icon, quit_button=None) | ||
self.menu = [u'翻墙浏览', u'配置代理'] | ||
|
||
@rumps.clicked(u'配置代理') | ||
def config(self, _): | ||
self.coordinator.IPC_open_admin_url() | ||
|
||
@rumps.clicked(u'翻墙浏览') | ||
def surf(self, _): | ||
self.coordinator.IPC_launch_browser() | ||
|
||
@rumps.clicked(u'退出') | ||
def quit(self, _): | ||
self.coordinator.IPC_quit() | ||
rumps.quit_application() | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import os | ||
|
||
from lib.ipc import ActorProcess | ||
from lib.systray import SysTrayIcon | ||
from lib.utils import init_logging | ||
|
||
class UI(ActorProcess): | ||
def __init__(self, coordinator): | ||
super(UI, self).__init__() | ||
self.coordinator = coordinator | ||
|
||
def systray_quit(self, systray_ref): | ||
pass | ||
|
||
def sytray_launch_browser(self, systray_ref): | ||
self.coordinator.IPC_launch_browser() | ||
|
||
def systray_open_webadmin(self, systray_ref): | ||
self.coordinator.IPC_open_admin_url() | ||
|
||
def run(self): | ||
init_logging() | ||
self.start_actor() | ||
rootdir = self.coordinator.get('rootdir') | ||
confdata = self.coordinator.get('confdata') | ||
icon = os.path.join(rootdir, confdata['icon_path']) | ||
SysTrayIcon( | ||
icon, | ||
u'萤火虫翻墙代理', | ||
( | ||
(u'翻墙浏览', None, self.sytray_launch_browser), | ||
(u'配置代理', None, self.systray_open_webadmin), | ||
(u'退出', None, 'QUIT') | ||
), | ||
on_quit=self.systray_quit, | ||
default_menu_index=1, | ||
) | ||
self.quit_actor() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import os | ||
|
||
from gevent import socket | ||
from gevent.pywsgi import WSGIServer | ||
|
||
from lib.ipc import ActorProcess | ||
from lib.utils import idle_port, init_logging | ||
|
||
class Admin(ActorProcess): | ||
def __init__(self, coordinator): | ||
super(Admin, self).__init__() | ||
self.coordinator = coordinator | ||
|
||
confdata = self.coordinator.get('confdata') | ||
self.ip = confdata['webadmin_ip'] | ||
self.port = confdata['webadmin_port'] | ||
|
||
def run(self): | ||
init_logging() | ||
rootdir = self.coordinator.get('rootdir') | ||
confdata = self.coordinator.get('confdata') | ||
webpath = os.path.join(rootdir, confdata['web_path']) | ||
os.chdir(webpath) | ||
|
||
from webpanel import app | ||
try: | ||
svr = WSGIServer((self.ip, self.port), application=app.create_app(self.coordinator), log=None) | ||
svr.serve_forever() | ||
except socket.error, e: # @UndefinedVariable | ||
print "failed to start web admin: %s, change port then try again" % str(e) | ||
self.port = idle_port() | ||
WSGIServer((self.ip, self.port), application=app.create_app(self.coordinator), log=None).serve_forever() | ||
|
||
def IPC_url(self): | ||
return "http://%s:%d/about" % (self.ip, self.port) | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.