Skip to content

Commit

Permalink
Merge branch 'master' into ui-autogen
Browse files Browse the repository at this point in the history
  • Loading branch information
mikakoi committed Jul 27, 2018
2 parents 7dc2f04 + 8dd60e8 commit d717521
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 46 deletions.
2 changes: 1 addition & 1 deletion dexbot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
APP_NAME = 'dexbot'
VERSION = '0.4.12'
VERSION = '0.4.13'
AUTHOR = 'Codaone Oy'
__version__ = VERSION
85 changes: 47 additions & 38 deletions dexbot/cli_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def select_choice(current, choices):
for tag, text in choices]


def process_config_element(elem, d, config):
def process_config_element(elem, whiptail, config):
""" Process an item of configuration metadata display a widget as appropriate
d: the Dialog object
config: the config dictionary for this worker
Expand All @@ -70,38 +70,38 @@ def process_config_element(elem, d, config):
title = elem.title

if elem.type == "string":
txt = d.prompt(title, config.get(elem.key, elem.default))
txt = whiptail.prompt(title, config.get(elem.key, elem.default))
if elem.extra:
while not re.match(elem.extra, txt):
d.alert("The value is not valid")
txt = d.prompt(
whiptail.alert("The value is not valid")
txt = whiptail.prompt(
title, config.get(
elem.key, elem.default))
config[elem.key] = txt
if elem.type == "bool":
value = config.get(elem.key, elem.default)
value = 'yes' if value else 'no'
config[elem.key] = d.confirm(title, value)
config[elem.key] = whiptail.confirm(title, value)
if elem.type in ("float", "int"):
txt = d.prompt(title, str(config.get(elem.key, elem.default)))
txt = whiptail.prompt(title, str(config.get(elem.key, elem.default)))
while True:
try:
if elem.type == "int":
val = int(txt)
else:
val = float(txt)
if val < elem.extra[0]:
d.alert("The value is too low")
whiptail.alert("The value is too low")
elif elem.extra[1] and val > elem.extra[1]:
d.alert("the value is too high")
whiptail.alert("the value is too high")
else:
break
except ValueError:
d.alert("Not a valid value")
txt = d.prompt(title, str(config.get(elem.key, elem.default)))
whiptail.alert("Not a valid value")
txt = whiptail.prompt(title, str(config.get(elem.key, elem.default)))
config[elem.key] = val
if elem.type == "choice":
config[elem.key] = d.radiolist(title, select_choice(
config[elem.key] = whiptail.radiolist(title, select_choice(
config.get(elem.key, elem.default), elem.extra))


Expand All @@ -116,24 +116,24 @@ def dexbot_service_running():
return False


def setup_systemd(d, config):
def setup_systemd(whiptail, config):
if not os.path.exists("/etc/systemd"):
return # No working systemd

if not d.confirm(
if not whiptail.confirm(
"Do you want to run dexbot as a background (daemon) process?"):
config['systemd_status'] = 'disabled'
return

redo_setup = False
if os.path.exists(SYSTEMD_SERVICE_NAME):
redo_setup = d.confirm('Redo systemd setup?', 'no')
redo_setup = whiptail.confirm('Redo systemd setup?', 'no')

if not os.path.exists(SYSTEMD_SERVICE_NAME) or redo_setup:
path = '~/.local/share/systemd/user'
path = os.path.expanduser(path)
pathlib.Path(path).mkdir(parents=True, exist_ok=True)
password = d.prompt(
password = whiptail.prompt(
"The wallet password\n"
"NOTE: this will be saved on disc so the worker can run unattended. "
"This means anyone with access to this computer's files can spend all your money",
Expand All @@ -154,13 +154,13 @@ def setup_systemd(d, config):
config['systemd_status'] = 'enabled'


def configure_worker(d, worker):
def configure_worker(whiptail, worker):
default_strategy = worker.get('module', 'dexbot.strategies.relative_orders')
for i in STRATEGIES:
if default_strategy == i['class']:
default_strategy = i['tag']

worker['module'] = d.radiolist(
worker['module'] = whiptail.radiolist(
"Choose a worker strategy", select_choice(
default_strategy, [(i['tag'], i['name']) for i in STRATEGIES]))
for i in STRATEGIES:
Expand All @@ -175,48 +175,57 @@ def configure_worker(d, worker):
configs = strategy_class.configure()
if configs:
for c in configs:
process_config_element(c, d, worker)
process_config_element(c, whiptail, worker)
else:
d.alert("This worker type does not have configuration information. "
"You will have to check the worker code and add configuration values to config.yml if required")
whiptail.alert(
"This worker type does not have configuration information. "
"You will have to check the worker code and add configuration values to config.yml if required")
return worker


def configure_dexbot(config, ctx):
d = get_whiptail()
whiptail = get_whiptail('DEXBot configure')
workers = config.get('workers', {})
if not workers:
while True:
txt = d.prompt("Your name for the worker")
config['workers'] = {txt: configure_worker(d, {})}
if not d.confirm("Set up another worker?\n(DEXBot can run multiple workers in one instance)"):
txt = whiptail.prompt("Your name for the worker")
config['workers'] = {txt: configure_worker(whiptail, {})}
if not whiptail.confirm("Set up another worker?\n(DEXBot can run multiple workers in one instance)"):
break
setup_systemd(d, config)
setup_systemd(whiptail, config)
else:
bitshares_instance = ctx.bitshares
action = d.menu("You have an existing configuration.\nSelect an action:",
[('NEW', 'Create a new worker'),
('DEL', 'Delete a worker'),
('EDIT', 'Edit a worker'),
('CONF', 'Redo general config')])
action = whiptail.menu(
"You have an existing configuration.\nSelect an action:",
[('NEW', 'Create a new worker'),
('DEL', 'Delete a worker'),
('EDIT', 'Edit a worker'),
('CONF', 'Redo general config')])

if action == 'EDIT':
worker_name = d.menu("Select worker to edit", [(i, i) for i in workers])
config['workers'][worker_name] = configure_worker(d, config['workers'][worker_name])
worker_name = whiptail.menu("Select worker to edit", [(i, i) for i in workers])
config['workers'][worker_name] = configure_worker(whiptail, config['workers'][worker_name])

strategy = BaseStrategy(worker_name, bitshares_instance=bitshares_instance)
strategy.purge()
elif action == 'DEL':
worker_name = d.menu("Select worker to delete", [(i, i) for i in workers])
worker_name = whiptail.menu("Select worker to delete", [(i, i) for i in workers])
del config['workers'][worker_name]

strategy = BaseStrategy(worker_name, bitshares_instance=bitshares_instance)
strategy.purge()
elif action == 'NEW':
txt = d.prompt("Your name for the new worker")
config['workers'][txt] = configure_worker(d, {})
txt = whiptail.prompt("Your name for the new worker")
config['workers'][txt] = configure_worker(whiptail, {})
elif action == 'CONF':
config['node'] = d.prompt("BitShares node to use", default=config['node'])
setup_systemd(d, config)
d.clear()
choice = whiptail.node_radiolist(
msg="Choose node",
items=select_choice(config['node'][0], [(i, i) for i in config['node']])
)
# Move selected node as first item in the config file's node list
config['node'].remove(choice)
config['node'].insert(0, choice)

setup_systemd(whiptail, config)
whiptail.clear()
return config
29 changes: 28 additions & 1 deletion dexbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def __init__(self, config=None, path=None):
self.create_config(self.default_data, self.config_file)
self._config = self.load_config(self.config_file)

# In case there is not a list of nodes in the config file,
# the node will be replaced by a list of pre-defined nodes.
if isinstance(self._config['node'], str):
self._config['node'] = self.node_list
self.save_config()

def __setitem__(self, key, value):
self._config[key] = value

Expand All @@ -52,7 +58,7 @@ def get(self, key, default=None):

@property
def default_data(self):
return {'node': 'wss://status200.bitshares.apasia.tech/ws', 'workers': {}}
return {'node': self.node_list, 'workers': {}}

@property
def workers_data(self):
Expand Down Expand Up @@ -158,3 +164,24 @@ def construct_mapping(mapping_loader, node):
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
construct_mapping)
return yaml.load(stream, OrderedLoader)

@property
def node_list(self):
""" A pre-defined list of Bitshares nodes. """
return [
"wss://eu.openledger.info/ws",
"wss://bitshares.openledger.info/ws",
"wss://dexnode.net/ws",
"wss://japan.bitshares.apasia.tech/ws",
"wss://bitshares-api.wancloud.io/ws",
"wss://openledger.hk/ws",
"wss://bitshares.apasia.tech/ws",
"wss://bitshares.crypto.fans/ws",
"wss://kc-us-dex.xeldal.com/ws",
"wss://api.bts.blckchnd.com",
"wss://btsza.co.za:8091/ws",
"wss://bitshares.dacplay.org/ws",
"wss://bit.btsabc.org/ws",
"wss://bts.ai.la/ws",
"wss://ws.gdex.top"
]
22 changes: 16 additions & 6 deletions dexbot/whiptail.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,26 @@ def menu(self, msg='', items=(), prefix=' - '):

def showlist(self, control, msg, items, prefix):
if isinstance(items[0], str):
items = [(i, '', 'OFF') for i in items]
items = [(tag, '', 'OFF') for tag in items]
else:
items = [(k, prefix + v, s) for k, v, s in items]
items = [(tag, prefix + value, state) for tag, value, state in items]
extra = self.calc_height(msg) + flatten(items)
return shlex.split(self.run(control, msg, extra).value)

def show_tag_only_list(self, control, msg, items, prefix):
if isinstance(items[0], str):
items = [(tag, '', 'OFF') for tag in items]
else:
items = [(tag, '', state) for tag, value, state in items]
extra = self.calc_height(msg) + flatten(items)
return shlex.split(self.run(control, msg, extra).value)

def radiolist(self, msg='', items=(), prefix=' - '):
return self.showlist('radiolist', msg, items, prefix)[0]

def node_radiolist(self, msg='', items=(), prefix=''):
return self.show_tag_only_list('radiolist', msg, items, prefix)[0]

def checklist(self, msg='', items=(), prefix=' - '):
return self.showlist('checklist', msg, items, prefix)

Expand Down Expand Up @@ -149,9 +160,8 @@ def clear(self):
pass # Don't tidy the screen


def get_whiptail():
def get_whiptail(title=''):
if shutil.which("whiptail"):
d = Whiptail()
return Whiptail(title=title)
else:
d = NoWhiptail() # Use our own fake whiptail
return d
return NoWhiptail() # Use our own fake whiptail

0 comments on commit d717521

Please sign in to comment.