-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmiguel.py
executable file
·153 lines (121 loc) · 4.28 KB
/
miguel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python
import json
import os
from cmd import Cmd
from functools import partial
from time import sleep
from traceback import format_exc
import readline
import click
import requests
from blessings import Terminal
from progressive.bar import Bar
from progressive.tree import ProgressTree, Value, BarDescriptor
# __version__ = "TODO Refactor this so that setup.py can import miguel and
# get version"
MAGDIR = os.path.expanduser("~/.magellan/miguel")
if not os.path.exists(MAGDIR):
print("Creating directory {}...".format(MAGDIR))
os.makedirs(MAGDIR)
HISTFILE = os.path.join(MAGDIR, "history")
if not os.path.exists(HISTFILE):
print("Creating {} file...".format(HISTFILE))
with open(HISTFILE, "w+") as f:
f.write("")
class Miguel(Cmd):
HTTP_VERBS = ["GET", "PUT", "POST", "PATCH", "DELETE"]
def __init__(self, base_url, *args, **kwargs):
Cmd.__init__(self, *args, **kwargs)
self.t = Terminal()
self.base_url = base_url
self.base_api_url = os.path.join(self.base_url, "api")
self._make_commands()
self.prompt = "{}\n$ ".format(
self.t.green("magellan_repl@{}".format(base_url))
)
readline.read_history_file(HISTFILE)
def _progress_loop(self, request_method, url, body):
response = request_method(url, data=json.dumps(body))
body = response.json()
max_tasks = body["num_total_tasks"]
bar = Bar(max_value=max_tasks, title="Completed Tasks",
num_rep="percentage", filled_color=2)
n = ProgressTree(term=self.t)
n.cursor.clear_lines(self.t.height - 1)
while True:
response = request_method(url, data=json.dumps(body))
body = response.json()
n.cursor.restore()
n.cursor.clear_lines(self.t.height - 1)
n.cursor.save()
bar.draw(value=body["num_finished_tasks"])
presp = body
presp["energy_history"] = sorted(presp["energy_history"])[:10]
del presp["best_location"]
print(json.dumps(presp, indent=4))
if response.status_code == 200:
return response
sleep(2.0)
def _parse_value(self, value):
transform_map = {
'True': 'true',
'False': 'false'
}
if value in transform_map:
value = transform_map[value]
try:
return json.loads(value)
except ValueError:
pass
# Handle cases like "2**16"
if value[0].isdigit() and value[-1].isdigit():
try:
return eval(value)
except (NameError, SyntaxError):
pass
return value
def command(self, verb, line):
chunks = line.strip().split()
route = "/".join(chunk for chunk in chunks if "=" not in chunk)
body = dict(chunk.split("=") for chunk in chunks if "=" in chunk)
body = {k: self._parse_value(value=v) for k, v in body.items()}
print(body)
url = "{}/{}".format(self.base_api_url, route)
request_method = getattr(requests, verb)
response = request_method(url, data=json.dumps(body))
if response.status_code == 202:
response = self._progress_loop(request_method, url, body)
print(json.dumps(response.json(), indent=4))
def _quit(self):
readline.write_history_file(HISTFILE)
def do_EOF(self, line):
self._quit()
return "Quitting"
def _make_commands(self):
def do_command(verb, line):
return self.command(verb, line)
for verb in self.HTTP_VERBS:
verb = verb.lower()
verb_func = partial(do_command, verb)
setattr(self, "do_{}".format(verb.lower()), verb_func)
def precmd(self, line):
if not line:
return line
if line.strip()[0] == "#":
return ""
return line
@click.command()
@click.option("-b", "--base-url", type=click.STRING, required=True)
def main(base_url):
repl = Miguel(base_url)
while True:
try:
repl.cmdloop()
print("")
break
except KeyboardInterrupt:
print("^C")
except Exception:
print(format_exc())
if __name__ == "__main__":
main()