diff options
author | Micah Lee <micah@micahflee.com> | 2019-11-02 21:00:23 -0700 |
---|---|---|
committer | Micah Lee <micah@micahflee.com> | 2019-11-02 21:00:23 -0700 |
commit | 1b36fe4036e5963ef702273b8d2218f5c043c4ed (patch) | |
tree | 96c0ee3c814b33dd0699b796f0483e8e0cf03ae8 /onionshare | |
parent | 69bd16527890c06b573b9f6b939bf72895daae95 (diff) | |
download | onionshare-1b36fe4036e5963ef702273b8d2218f5c043c4ed.tar.gz onionshare-1b36fe4036e5963ef702273b8d2218f5c043c4ed.zip |
Make ModeSettings be able to save and load
Diffstat (limited to 'onionshare')
-rw-r--r-- | onionshare/__init__.py | 53 | ||||
-rw-r--r-- | onionshare/common.py | 15 | ||||
-rw-r--r-- | onionshare/mode_settings.py | 75 |
3 files changed, 107 insertions, 36 deletions
diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 7bc18bff..f532ec0e 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -73,21 +73,21 @@ def main(cwd=None): ) parser.add_argument( "--connect-timeout", - metavar="<int>", + metavar="SECONDS", dest="connect_timeout", default=120, help="Give up connecting to Tor after a given amount of seconds (default: 120)", ) parser.add_argument( "--config", - metavar="config", + metavar="FILENAME", default=None, help="Filename of custom global settings", ) # Persistent file parser.add_argument( "--persistent", - metavar="persistent", + metavar="FILENAME", default=None, help="Filename of persistent session", ) @@ -101,14 +101,14 @@ def main(cwd=None): ) parser.add_argument( "--auto-start-timer", - metavar="<int>", + metavar="SECONDS", dest="autostart_timer", default=0, help="Start onion service at scheduled time (N seconds from now)", ) parser.add_argument( "--auto-stop-timer", - metavar="<int>", + metavar="SECONDS", dest="autostop_timer", default=0, help="Stop onion service at schedule time (N seconds from now)", @@ -174,8 +174,8 @@ def main(cwd=None): website = bool(args.website) local_only = bool(args.local_only) connect_timeout = int(args.connect_timeout) - config = args.config - persistent = args.persistent + config_filename = args.config + persistent_filename = args.persistent public = bool(args.public) autostart_timer = int(args.autostart_timer) autostop_timer = int(args.autostop_timer) @@ -220,8 +220,8 @@ def main(cwd=None): sys.exit() # Re-load settings, if a custom config was passed in - if config: - common.load_settings(config) + if config_filename: + common.load_settings(config_filename) else: common.load_settings() @@ -229,21 +229,24 @@ def main(cwd=None): common.verbose = verbose # Mode settings - mode_settings = ModeSettings(common) - mode_settings.set("general", "public", public) - mode_settings.set("general", "autostart_timer", autostart_timer) - mode_settings.set("general", "autostop_timer", autostop_timer) - mode_settings.set("general", "legacy", legacy) - mode_settings.set("general", "client_auth", client_auth) - if mode == "share": - mode_settings.set("share", "autostop_sharing", autostop_sharing) - if mode == "receive": - if data_dir: - mode_settings.set("receive", "data_dir", data_dir) - if mode == "website": - mode_settings.set("website", "disable_csp", disable_csp) - - # TODO: handle persistent + if persistent_filename: + mode_settings = ModeSettings(common, persistent_filename) + mode_settings.set("persistent", "enabled", True) + else: + mode_settings = ModeSettings(common) + if mode_settings.just_created: + mode_settings.set("general", "public", public) + mode_settings.set("general", "autostart_timer", autostart_timer) + mode_settings.set("general", "autostop_timer", autostop_timer) + mode_settings.set("general", "legacy", legacy) + mode_settings.set("general", "client_auth", client_auth) + if mode == "share": + mode_settings.set("share", "autostop_sharing", autostop_sharing) + if mode == "receive": + if data_dir: + mode_settings.set("receive", "data_dir", data_dir) + if mode == "website": + mode_settings.set("website", "disable_csp", disable_csp) # Create the Web object web = Web(common, False, mode_settings, mode) @@ -253,7 +256,7 @@ def main(cwd=None): try: onion.connect( custom_settings=False, - config=config, + config=config_filename, connect_timeout=connect_timeout, local_only=local_only, ) diff --git a/onionshare/common.py b/onionshare/common.py index ac79f43b..5245ddf9 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -177,15 +177,24 @@ class Common: os.makedirs(onionshare_data_dir, 0o700, True) return onionshare_data_dir - def build_password(self): + def build_persistent_dir(self): """ - Returns a random string made from two words from the wordlist, such as "deter-trig". + Returns the path to the folder that holds persistent files + """ + onionshare_data_dir = self.build_data_dir() + persistent_dir = os.path.join(onionshare_data_dir, "persistent") + os.makedirs(persistent_dir, 0o700, True) + return persistent_dir + + def build_password(self, word_count=2): + """ + Returns a random string made of words from the wordlist, such as "deter-trig". """ 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(word_count)) @staticmethod def random_string(num_bytes, output_len=None): diff --git a/onionshare/mode_settings.py b/onionshare/mode_settings.py index 2eab8f6e..ffc32d06 100644 --- a/onionshare/mode_settings.py +++ b/onionshare/mode_settings.py @@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. """ import os import pwd +import json class ModeSettings: @@ -27,10 +28,10 @@ class ModeSettings: is only one TabSettings, and in the GUI there is a separate TabSettings for each tab """ - def __init__(self, common): + def __init__(self, common, filename=None): self.common = common - self.settings = { + self.default_settings = { "persistent": { "enabled": False, "private_key": None, @@ -44,16 +45,41 @@ class ModeSettings: "legacy": False, "client_auth": False, }, - "share": {"autostop_sharing": True}, + "share": {"autostop_sharing": True, "filenames": []}, "receive": {"data_dir": self.build_default_receive_data_dir()}, - "website": {"disable_csp": False}, + "website": {"disable_csp": False, "filenames": []}, } + self._settings = {} + + self.just_created = False + self.id = self.common.build_password(3) + + self.load(filename) + + def fill_in_defaults(self): + """ + If there are any missing settings from self._settings, replace them with + their default values. + """ + for key in self.default_settings: + if key in self._settings: + for inner_key in self.default_settings[key]: + if inner_key not in self._settings[key]: + self._settings[key][inner_key] = self.default_settings[key][ + inner_key + ] + else: + self._settings[key] = self.default_settings[key] def get(self, group, key): - return self.settings[group][key] + return self._settings[group][key] def set(self, group, key, val): - self.settings[group][key] = val + self._settings[group][key] = val + self.common.log( + "ModeSettings", "set", f"updating {self.id}: {group}.{key} = {val}" + ) + self.save() def build_default_receive_data_dir(self): """ @@ -73,6 +99,39 @@ class ModeSettings: # All other OSes return os.path.expanduser("~/OnionShare") + def load(self, filename=None): + # Load persistent settings from disk. If the file doesn't exist, create it + if filename: + self.filename = filename + else: + # Give it a persistent filename + self.filename = os.path.join( + self.common.build_persistent_dir(), f"{self.id}.json" + ) + + if os.path.exists(self.filename): + try: + with open(self.filename, "r") as f: + self._settings = json.load(f) + self.fill_in_defaults() + self.common.log("ModeSettings", "load", f"loaded {self.filename}") + return + except: + pass + + # If loading settings didn't work, create the settings file + self.common.log("ModeSettings", "load", f"creating {self.filename}") + self.fill_in_defaults() + self.just_created = True + def save(self): - # TODO: save settings, if persistent - pass + # Save persistent setting to disk + if not self.get("persistent", "enabled"): + self.common.log( + "ModeSettings", "save", f"{self.id}: not persistent, so not saving" + ) + return + + if self.filename: + with open(self.filename, "w") as file: + file.write(json.dumps(self._settings, indent=2)) |