From 1de668a9e5ac8bf09768e7b3a85fa54c7b2cf8d9 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sat, 30 Nov 2019 02:42:49 -0600 Subject: [PATCH] onboarding work, now waits to start daemon timers --- src/communicator/__init__.py | 71 +++++++++++++++--------- src/config/__init__.py | 2 + src/config/onboarding.py | 30 +++++++++- src/httpapi/miscclientapi/endpoints.py | 4 ++ src/onionrcommands/daemonlaunch.py | 2 + src/onionrtypes/__init__.py | 2 + static-data/default_config.json | 4 ++ static-data/www/onboarding/onboarding.js | 2 + static-data/www/shared/panel.js | 13 +++++ 9 files changed, 102 insertions(+), 28 deletions(-) diff --git a/src/communicator/__init__.py b/src/communicator/__init__.py index 734bd5d7..52001089 100755 --- a/src/communicator/__init__.py +++ b/src/communicator/__init__.py @@ -4,6 +4,36 @@ This file contains both the OnionrCommunicate class for communcating with peers and code to operate as a daemon, getting commands from the command queue database (see core.Core.daemonQueue) ''' +import os +import time + +import config +import logger +import onionrpeers +import onionrplugins as plugins +from . import onlinepeers, uploadqueue +from communicatorutils import servicecreator +from communicatorutils import onionrcommunicatortimers +from communicatorutils import downloadblocks +from communicatorutils import lookupblocks +from communicatorutils import lookupadders +from communicatorutils import connectnewpeers +from communicatorutils import uploadblocks +from communicatorutils import daemonqueuehandler +from communicatorutils import announcenode, deniableinserts +from communicatorutils import cooldownpeer +from communicatorutils import housekeeping +from communicatorutils import netcheck +from onionrutils import localcommand +from onionrutils import epoch +from etc import humanreadabletime +import onionrservices +import filepaths +from onionrblocks import storagecounter +from coredb import daemonqueue +from coredb import dbfiles +from netcontroller import NetController + ''' This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,37 +48,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sys, os, time -import config, logger -import onionrexceptions, onionrpeers -from onionrblocks import onionrblockapi as block -from onionrplugins import onionrevents as events -import onionrplugins as plugins -from . import onlinepeers, uploadqueue -from communicatorutils import servicecreator, onionrcommunicatortimers -from communicatorutils import downloadblocks, lookupblocks, lookupadders -from communicatorutils import servicecreator, connectnewpeers -from communicatorutils import uploadblocks -from communicatorutils import daemonqueuehandler, announcenode, deniableinserts -from communicatorutils import cooldownpeer, housekeeping, netcheck -from onionrutils import localcommand, epoch -from etc import humanreadabletime -import onionrservices, filepaths -from onionrblocks import storagecounter -from coredb import daemonqueue, dbfiles -from utils import gettransports -from netcontroller import NetController OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers config.reload() class OnionrCommunicatorDaemon: - def __init__(self, shared_state, developmentMode=config.get('general.dev_mode', False)): + def __init__(self, shared_state, developmentMode=None): + if developmentMode is None: + developmentMode = config.get('general.dev_mode', False) + # configure logger and stuff self.config = config self.storage_counter = storagecounter.StorageCounter() - self.isOnline = True # Assume we're connected to the internet - self.shared_state = shared_state # TooManyObjects module + self.isOnline = True # Assume we're connected to the internet + self.shared_state = shared_state # TooManyObjects module # list of timer instances self.timers = [] @@ -69,8 +82,10 @@ class OnionrCommunicatorDaemon: self.offlinePeers = [] self.cooldownPeer = {} self.connectTimes = {} - self.peerProfiles = [] # list of peer's profiles (onionrpeers.PeerProfile instances) - self.newPeers = [] # Peers merged to us. Don't add to db until we know they're reachable + # list of peer's profiles (onionrpeers.PeerProfile instances) + self.peerProfiles = [] + # Peers merged to us. Don't add to db until we know they're reachable + self.newPeers = [] self.announceProgress = {} self.announceCache = {} @@ -182,6 +197,12 @@ class OnionrCommunicatorDaemon: if config.get('general.use_bootstrap', True): bootstrappeers.add_bootstrap_list_to_peer_list(self, [], db_only=True) + if not config.get('onboarding.done', True): + logger.info('First run detected. Run openhome to get setup.', terminal=True) + + while not config.get('onboarding.done', True): + time.sleep(5) + # Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking try: while not self.shutdown: diff --git a/src/config/__init__.py b/src/config/__init__.py index bc26c1aa..7f8b0e79 100755 --- a/src/config/__init__.py +++ b/src/config/__init__.py @@ -21,6 +21,8 @@ import os, json, logger import filepaths +from . import onboarding + _configfile = filepaths.config_file _config = {} diff --git a/src/config/onboarding.py b/src/config/onboarding.py index 66141196..217f5903 100644 --- a/src/config/onboarding.py +++ b/src/config/onboarding.py @@ -4,9 +4,12 @@ Setup config from onboarding choices """ from pathlib import Path +from typing import Union from filepaths import onboarding_mark_file -import onionrtypes +from onionrtypes import JSONSerializable +from onionrtypes import OnboardingConfig +import config """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,8 +26,29 @@ import onionrtypes """ -def set_config_from_onboarding(config_settings: onionrtypes.OnboardingConfig): - return +def _get_val_or_none(json: dict, key: str) -> Union[None, JSONSerializable]: + try: + return json['configInfo'][key] + except KeyError: + return None + + +def set_config_from_onboarding(config_settings: OnboardingConfig): + + network_security_level = 0 + theme = "dark" + + if _get_val_or_none(config_settings, 'stateTarget') == True: + config.set('general.security_level', 1) + + if _get_val_or_none(config_settings, 'useDark') == False: + config.set('ui.theme', 'light') + + config.set('general.store_plaintext_blocks', + _get_val_or_none(config_settings, 'plainContrib')) + + + config.set('onboarding.done', True, savefile=True) def set_onboarding_finished(): """Create the onboarding completed setting file""" diff --git a/src/httpapi/miscclientapi/endpoints.py b/src/httpapi/miscclientapi/endpoints.py index 4f49f094..46459369 100644 --- a/src/httpapi/miscclientapi/endpoints.py +++ b/src/httpapi/miscclientapi/endpoints.py @@ -140,3 +140,7 @@ class PrivateEndpoints: @private_endpoints_bp.route('/gettorsocks') def get_tor_socks(): return Response(str(client_api._too_many.get(NetController).socksPort)) + + @private_endpoints_bp.route('/setonboarding', methods=['POST']) + def set_onboarding(): + return Response(config.onboarding.set_config_from_onboarding(request.get_json())) diff --git a/src/onionrcommands/daemonlaunch.py b/src/onionrcommands/daemonlaunch.py index 63ff512b..72d648f6 100755 --- a/src/onionrcommands/daemonlaunch.py +++ b/src/onionrcommands/daemonlaunch.py @@ -20,6 +20,7 @@ import os, time, sys, platform, sqlite3, signal from threading import Thread +from gevent import time import toomanyobjs @@ -104,6 +105,7 @@ def daemon(): time.sleep(1) except KeyboardInterrupt: pass + events.event('init', threaded = False) events.event('daemon_start') communicator.startCommunicator(shared_state) diff --git a/src/onionrtypes/__init__.py b/src/onionrtypes/__init__.py index 7b881270..37cf3c51 100644 --- a/src/onionrtypes/__init__.py +++ b/src/onionrtypes/__init__.py @@ -8,3 +8,5 @@ DeterministicKeyPassphrase = NewType('DeterministicKeyPassphrase', str) BlockHash = NewType('BlockHash', str) OnboardingConfig = NewType('OnboardingConfig', str) + +JSONSerializable = NewType('JSONSerializable', str) diff --git a/static-data/default_config.json b/static-data/default_config.json index d8ff8e7e..05c89fc6 100755 --- a/static-data/default_config.json +++ b/static-data/default_config.json @@ -73,5 +73,9 @@ "timers": { "lookupBlocks": 25, "getBlocks": 10 + }, + + "onboarding": { + "done": false } } diff --git a/static-data/www/onboarding/onboarding.js b/static-data/www/onboarding/onboarding.js index 5e60e5a8..bde0f8b9 100644 --- a/static-data/www/onboarding/onboarding.js +++ b/static-data/www/onboarding/onboarding.js @@ -39,6 +39,7 @@ function sendConfig(configInfo){ }, body: JSON.stringify({configInfo}) }).then(function(data) { + window.location.href = window.location.origin + '/' + window.location.hash }) } @@ -54,6 +55,7 @@ document.getElementById('onboardingForm').onsubmit = function(e){ submitInfo.deterministic = getCheckValue('useDeterministic') submitInfo.mail = getCheckValue('useMail') submitInfo.circles = getCheckValue('useCircles') + submitInfo.useDark = getCheckValue('useDarkTheme') if (submitInfo.donate){ openDonateModal(submitInfo) diff --git a/static-data/www/shared/panel.js b/static-data/www/shared/panel.js index c88cf552..671ab40d 100755 --- a/static-data/www/shared/panel.js +++ b/static-data/www/shared/panel.js @@ -41,3 +41,16 @@ restartBtn.onclick = function(){ } } + +fetch('/config/get/onboarding.done', { + method: 'GET', + headers: { + "content-type": "application/json", + "token": webpass + }}) +.then((resp) => resp.text()) // Transform the data into text +.then(function(data) { + if (data === 'false'){ + window.location.href = window.location.pathname = "/onboarding/" + window.location.hash + } + }) \ No newline at end of file