diff options
Diffstat (limited to 'onionshare/common.py')
-rw-r--r-- | onionshare/common.py | 256 |
1 files changed, 138 insertions, 118 deletions
diff --git a/onionshare/common.py b/onionshare/common.py index 325f11d4..3373462b 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -36,16 +36,17 @@ class Common(object): """ The Common object is shared amongst all parts of OnionShare. """ + def __init__(self, verbose=False): self.verbose = verbose # The platform OnionShare is running on self.platform = platform.system() - if self.platform.endswith('BSD'): - self.platform = 'BSD' + if self.platform.endswith("BSD") or self.platform == "DragonFly": + self.platform = "BSD" # The current version of OnionShare - with open(self.get_resource_path('version.txt')) as f: + with open(self.get_resource_path("version.txt")) as f: self.version = f.read().strip() def load_settings(self, config=None): @@ -64,7 +65,7 @@ class Common(object): final_msg = "[{}] {}.{}".format(timestamp, module, func) if msg: - final_msg = '{}: {}'.format(final_msg, msg) + final_msg = "{}: {}".format(final_msg, msg) print(final_msg) def get_resource_path(self, filename): @@ -73,85 +74,118 @@ class Common(object): systemwide, and whether regardless of platform """ # On Windows, and in Windows dev mode, switch slashes in incoming filename to backslackes - if self.platform == 'Windows': - filename = filename.replace('/', '\\') + if self.platform == "Windows": + filename = filename.replace("/", "\\") - if getattr(sys, 'onionshare_dev_mode', False): + if getattr(sys, "onionshare_dev_mode", False): # Look for resources directory relative to python file - prefix = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'share') + prefix = os.path.join( + os.path.dirname( + os.path.dirname( + os.path.abspath(inspect.getfile(inspect.currentframe())) + ) + ), + "share", + ) if not os.path.exists(prefix): # While running tests during stdeb bdist_deb, look 3 directories up for the share folder - prefix = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(prefix)))), 'share') - - elif self.platform == 'BSD' or self.platform == 'Linux': + prefix = os.path.join( + os.path.dirname( + os.path.dirname(os.path.dirname(os.path.dirname(prefix))) + ), + "share", + ) + + elif self.platform == "BSD" or self.platform == "Linux": # Assume OnionShare is installed systemwide in Linux, since we're not running in dev mode - prefix = os.path.join(sys.prefix, 'share/onionshare') + prefix = os.path.join(sys.prefix, "share/onionshare") - elif getattr(sys, 'frozen', False): + elif getattr(sys, "frozen", False): # Check if app is "frozen" # https://pythonhosted.org/PyInstaller/#run-time-information - if self.platform == 'Darwin': - prefix = os.path.join(sys._MEIPASS, 'share') - elif self.platform == 'Windows': - prefix = os.path.join(os.path.dirname(sys.executable), 'share') + if self.platform == "Darwin": + prefix = os.path.join(sys._MEIPASS, "share") + elif self.platform == "Windows": + prefix = os.path.join(os.path.dirname(sys.executable), "share") return os.path.join(prefix, filename) def get_tor_paths(self): - if self.platform == 'Linux': - tor_path = '/usr/bin/tor' - tor_geo_ip_file_path = '/usr/share/tor/geoip' - tor_geo_ipv6_file_path = '/usr/share/tor/geoip6' - obfs4proxy_file_path = '/usr/bin/obfs4proxy' - elif self.platform == 'Windows': - base_path = os.path.join(os.path.dirname(os.path.dirname(self.get_resource_path(''))), 'tor') - tor_path = os.path.join(os.path.join(base_path, 'Tor'), 'tor.exe') - obfs4proxy_file_path = os.path.join(os.path.join(base_path, 'Tor'), 'obfs4proxy.exe') - tor_geo_ip_file_path = os.path.join(os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip') - tor_geo_ipv6_file_path = os.path.join(os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip6') - elif self.platform == 'Darwin': - base_path = os.path.dirname(os.path.dirname(os.path.dirname(self.get_resource_path('')))) - tor_path = os.path.join(base_path, 'Resources', 'Tor', 'tor') - tor_geo_ip_file_path = os.path.join(base_path, 'Resources', 'Tor', 'geoip') - tor_geo_ipv6_file_path = os.path.join(base_path, 'Resources', 'Tor', 'geoip6') - obfs4proxy_file_path = os.path.join(base_path, 'Resources', 'Tor', 'obfs4proxy') - elif self.platform == 'BSD': - tor_path = '/usr/local/bin/tor' - tor_geo_ip_file_path = '/usr/local/share/tor/geoip' - tor_geo_ipv6_file_path = '/usr/local/share/tor/geoip6' - obfs4proxy_file_path = '/usr/local/bin/obfs4proxy' - - return (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path, obfs4proxy_file_path) + if self.platform == "Linux": + tor_path = "/usr/bin/tor" + tor_geo_ip_file_path = "/usr/share/tor/geoip" + tor_geo_ipv6_file_path = "/usr/share/tor/geoip6" + obfs4proxy_file_path = "/usr/bin/obfs4proxy" + elif self.platform == "Windows": + base_path = os.path.join( + os.path.dirname(os.path.dirname(self.get_resource_path(""))), "tor" + ) + tor_path = os.path.join(os.path.join(base_path, "Tor"), "tor.exe") + obfs4proxy_file_path = os.path.join( + os.path.join(base_path, "Tor"), "obfs4proxy.exe" + ) + tor_geo_ip_file_path = os.path.join( + os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip" + ) + tor_geo_ipv6_file_path = os.path.join( + os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip6" + ) + elif self.platform == "Darwin": + base_path = os.path.dirname( + os.path.dirname(os.path.dirname(self.get_resource_path(""))) + ) + tor_path = os.path.join(base_path, "Resources", "Tor", "tor") + tor_geo_ip_file_path = os.path.join(base_path, "Resources", "Tor", "geoip") + tor_geo_ipv6_file_path = os.path.join( + base_path, "Resources", "Tor", "geoip6" + ) + obfs4proxy_file_path = os.path.join( + base_path, "Resources", "Tor", "obfs4proxy" + ) + elif self.platform == "BSD": + tor_path = "/usr/local/bin/tor" + tor_geo_ip_file_path = "/usr/local/share/tor/geoip" + tor_geo_ipv6_file_path = "/usr/local/share/tor/geoip6" + obfs4proxy_file_path = "/usr/local/bin/obfs4proxy" + + return ( + tor_path, + tor_geo_ip_file_path, + tor_geo_ipv6_file_path, + obfs4proxy_file_path, + ) def build_data_dir(self): """ Returns the path of the OnionShare data directory. """ - if self.platform == 'Windows': + if self.platform == "Windows": try: - appdata = os.environ['APPDATA'] - onionshare_data_dir = '{}\\OnionShare'.format(appdata) + appdata = os.environ["APPDATA"] + onionshare_data_dir = "{}\\OnionShare".format(appdata) except: # If for some reason we don't have the 'APPDATA' environment variable # (like running tests in Linux while pretending to be in Windows) - onionshare_data_dir = os.path.expanduser('~/.config/onionshare') - elif self.platform == 'Darwin': - onionshare_data_dir = os.path.expanduser('~/Library/Application Support/OnionShare') + onionshare_data_dir = os.path.expanduser("~/.config/onionshare") + elif self.platform == "Darwin": + onionshare_data_dir = os.path.expanduser( + "~/Library/Application Support/OnionShare" + ) else: - onionshare_data_dir = os.path.expanduser('~/.config/onionshare') + onionshare_data_dir = os.path.expanduser("~/.config/onionshare") os.makedirs(onionshare_data_dir, 0o700, True) return onionshare_data_dir - def build_slug(self): + def build_password(self): """ Returns a random string made from two words from the wordlist, such as "deter-trig". """ - with open(self.get_resource_path('wordlist.txt')) as f: + with open(self.get_resource_path("wordlist.txt")) as f: wordlist = f.read().split() r = random.SystemRandom() - return '-'.join(r.choice(wordlist) for _ in range(2)) + return "-".join(r.choice(wordlist) for _ in range(2)) def define_css(self): """ @@ -160,7 +194,7 @@ class Common(object): """ self.css = { # OnionShareGui styles - 'mode_switcher_selected_style': """ + "mode_switcher_selected_style": """ QPushButton { color: #ffffff; background-color: #4e064f; @@ -169,8 +203,7 @@ class Common(object): font-weight: bold; border-radius: 0; }""", - - 'mode_switcher_unselected_style': """ + "mode_switcher_unselected_style": """ QPushButton { color: #ffffff; background-color: #601f61; @@ -178,23 +211,20 @@ class Common(object): font-weight: normal; border-radius: 0; }""", - - 'settings_button': """ + "settings_button": """ QPushButton { background-color: #601f61; border: 0; border-left: 1px solid #69266b; border-radius: 0; }""", - - 'server_status_indicator_label': """ + "server_status_indicator_label": """ QLabel { font-style: italic; color: #666666; padding: 2px; }""", - - 'status_bar': """ + "status_bar": """ QStatusBar { font-style: italic; color: #666666; @@ -202,16 +232,14 @@ class Common(object): QStatusBar::item { border: 0px; }""", - - # Common styles between ShareMode and ReceiveMode and their child widgets - 'mode_info_label': """ + # Common styles between modes and their child widgets + "mode_info_label": """ QLabel { font-size: 12px; color: #666666; } """, - - 'server_status_url': """ + "server_status_url": """ QLabel { background-color: #ffffff; color: #000000; @@ -220,14 +248,12 @@ class Common(object): font-size: 12px; } """, - - 'server_status_url_buttons': """ + "server_status_url_buttons": """ QPushButton { color: #3f7fcf; } """, - - 'server_status_button_stopped': """ + "server_status_button_stopped": """ QPushButton { background-color: #5fa416; color: #ffffff; @@ -235,8 +261,7 @@ class Common(object): border: 0; border-radius: 5px; }""", - - 'server_status_button_working': """ + "server_status_button_working": """ QPushButton { background-color: #4c8211; color: #ffffff; @@ -245,8 +270,7 @@ class Common(object): border-radius: 5px; font-style: italic; }""", - - 'server_status_button_started': """ + "server_status_button_started": """ QPushButton { background-color: #d0011b; color: #ffffff; @@ -254,8 +278,7 @@ class Common(object): border: 0; border-radius: 5px; }""", - - 'downloads_uploads_empty': """ + "downloads_uploads_empty": """ QWidget { background-color: #ffffff; border: 1px solid #999999; @@ -265,13 +288,11 @@ class Common(object): border: 0px; } """, - - 'downloads_uploads_empty_text': """ + "downloads_uploads_empty_text": """ QLabel { color: #999999; }""", - - 'downloads_uploads_label': """ + "downloads_uploads_label": """ QLabel { font-weight: bold; font-size 14px; @@ -279,14 +300,12 @@ class Common(object): background-color: none; border: none; }""", - - 'downloads_uploads_clear': """ + "downloads_uploads_clear": """ QPushButton { color: #3f7fcf; } """, - - 'download_uploads_indicator': """ + "download_uploads_indicator": """ QLabel { color: #ffffff; background-color: #f44449; @@ -296,8 +315,7 @@ class Common(object): border-radius: 7px; text-align: center; }""", - - 'downloads_uploads_progress_bar': """ + "downloads_uploads_progress_bar": """ QProgressBar { border: 1px solid #4e064f; background-color: #ffffff !important; @@ -309,9 +327,20 @@ class Common(object): background-color: #4e064f; width: 10px; }""", - + "history_individual_file_timestamp_label": """ + QLabel { + color: #666666; + }""", + "history_individual_file_status_code_label_2xx": """ + QLabel { + color: #008800; + }""", + "history_individual_file_status_code_label_4xx": """ + QLabel { + color: #cc0000; + }""", # Share mode and child widget styles - 'share_zip_progess_bar': """ + "share_zip_progess_bar": """ QProgressBar { border: 1px solid #4e064f; background-color: #ffffff !important; @@ -323,21 +352,18 @@ class Common(object): background-color: #4e064f; width: 10px; }""", - - 'share_filesize_warning': """ + "share_filesize_warning": """ QLabel { padding: 10px 0; font-weight: bold; color: #333333; } """, - - 'share_file_selection_drop_here_label': """ + "share_file_selection_drop_here_label": """ QLabel { color: #999999; }""", - - 'share_file_selection_drop_count_label': """ + "share_file_selection_drop_count_label": """ QLabel { color: #ffffff; background-color: #f44449; @@ -345,60 +371,51 @@ class Common(object): padding: 5px 10px; border-radius: 10px; }""", - - 'share_file_list_drag_enter': """ + "share_file_list_drag_enter": """ FileList { border: 3px solid #538ad0; } """, - - 'share_file_list_drag_leave': """ + "share_file_list_drag_leave": """ FileList { border: none; } """, - - 'share_file_list_item_size': """ + "share_file_list_item_size": """ QLabel { color: #666666; font-size: 11px; }""", - # Receive mode and child widget styles - 'receive_file': """ + "receive_file": """ QWidget { background-color: #ffffff; } """, - - 'receive_file_size': """ + "receive_file_size": """ QLabel { color: #666666; font-size: 11px; }""", - # Settings dialog - 'settings_version': """ + "settings_version": """ QLabel { color: #666666; }""", - - 'settings_tor_status': """ + "settings_tor_status": """ QLabel { background-color: #ffffff; color: #000000; padding: 10px; }""", - - 'settings_whats_this': """ + "settings_whats_this": """ QLabel { font-size: 12px; }""", - - 'settings_connect_to_tor': """ + "settings_connect_to_tor": """ QLabel { font-style: italic; - }""" + }""", } @staticmethod @@ -408,7 +425,7 @@ class Common(object): """ b = os.urandom(num_bytes) h = hashlib.sha256(b).digest()[:16] - s = base64.b32encode(h).lower().replace(b'=', b'').decode('utf-8') + s = base64.b32encode(h).lower().replace(b"=", b"").decode("utf-8") if not output_len: return s return s[:output_len] @@ -420,14 +437,14 @@ class Common(object): """ thresh = 1024.0 if b < thresh: - return '{:.1f} B'.format(b) - units = ('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB') + return "{:.1f} B".format(b) + units = ("KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") u = 0 b /= thresh while b >= thresh: b /= thresh u += 1 - return '{:.1f} {}'.format(b, units[u]) + return "{:.1f} {}".format(b, units[u]) @staticmethod def format_seconds(seconds): @@ -445,7 +462,7 @@ class Common(object): human_readable.append("{:.0f}m".format(minutes)) if seconds or not human_readable: human_readable.append("{:.0f}s".format(seconds)) - return ''.join(human_readable) + return "".join(human_readable) @staticmethod def estimated_time_remaining(bytes_downloaded, total_bytes, started): @@ -489,6 +506,7 @@ class AutoStopTimer(threading.Thread): """ Background thread sleeps t hours and returns. """ + def __init__(self, common, time): threading.Thread.__init__(self) @@ -498,6 +516,8 @@ class AutoStopTimer(threading.Thread): self.time = time def run(self): - self.common.log('AutoStopTimer', 'Server will shut down after {} seconds'.format(self.time)) + self.common.log( + "AutoStopTimer", "Server will shut down after {} seconds".format(self.time) + ) time.sleep(self.time) return 1 |