|
1 | | -import collections |
2 | | - |
3 | | -import six |
4 | | -from prompt_toolkit import Application |
5 | | -from prompt_toolkit.application import get_app |
6 | | -from prompt_toolkit.key_binding import KeyBindings |
7 | | -from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous |
8 | | -from prompt_toolkit.layout import Layout, VSplit, HSplit, FloatContainer, Float |
9 | | -from prompt_toolkit.shortcuts import message_dialog |
10 | | -from prompt_toolkit.styles import Style |
11 | | -from prompt_toolkit.widgets import Frame, Label, TextArea, RadioList, Box, Button, Dialog |
12 | | - |
13 | | -from gradient import client, config |
14 | | -from gradient.cli import common |
15 | 1 | from gradient.commands import projects as projects_commands |
| 2 | +from gradient.wizards import wizard |
| 3 | +from gradient.wizards.wizard import get_application |
16 | 4 |
|
17 | | -if not six.PY2: |
18 | | - unicode = str |
19 | | - |
20 | | -bindings = KeyBindings() |
21 | | -bindings.add(u'tab')(focus_next) |
22 | | -bindings.add(u"right")(focus_next) |
23 | | -bindings.add(u'enter')(focus_next) |
24 | | -bindings.add(u"left")(focus_previous) |
25 | | -bindings.add(u's-tab')(focus_previous) |
26 | | - |
27 | | - |
28 | | -@bindings.add(u"c-c") |
29 | | -def _(event): |
30 | | - event.app.exit() |
31 | | - |
32 | | - |
33 | | -@bindings.add('c-space') |
34 | | -def _(event): |
35 | | - " Initialize autocompletion, or select the next completion. " |
36 | | - buff = event.app.current_buffer |
37 | | - if buff.complete_state: |
38 | | - buff.complete_next() |
39 | | - else: |
40 | | - buff.start_completion(select_first=False) |
41 | | - |
42 | | - |
43 | | -default_question_style = u"green" |
44 | | - |
45 | | - |
46 | | -class Question(object): |
47 | | - def __init__(self, question): |
48 | | - self.question = question |
49 | | - self.question_widget = self._get_question_widget() |
50 | | - self.answer_widget = self._get_answer_widget() |
51 | | - self.widget = self._get_widget() |
52 | | - |
53 | | - @property |
54 | | - def answer(self): |
55 | | - return self.answer_widget.text |
56 | | - |
57 | | - def _get_question_widget(self): |
58 | | - return Label( |
59 | | - self.question, |
60 | | - # style=self.style, |
61 | | - ) |
62 | | - |
63 | | - def _get_answer_widget(self): |
64 | | - return TextArea(multiline=False) |
65 | | - |
66 | | - def _get_widget(self): |
67 | | - return Frame( |
68 | | - VSplit( |
69 | | - [ |
70 | | - self.question_widget, |
71 | | - self.answer_widget, |
72 | | - ], |
73 | | - ), |
74 | | - ) |
75 | | - |
76 | | - |
77 | | -class RadioQuestion(Question): |
78 | | - def __init__(self, question, answers): |
79 | | - self.answers = answers |
80 | | - super(RadioQuestion, self).__init__(question) |
81 | | - |
82 | | - @property |
83 | | - def answer(self): |
84 | | - return self.answer_widget.current_value |
85 | | - |
86 | | - def _get_answer_widget(self): |
87 | | - return RadioList(self.answers) |
88 | | - |
89 | | - |
90 | | -class Questions(object): |
91 | | - def __init__(self): |
92 | | - self._questions = collections.OrderedDict() |
93 | | - |
94 | | - def add_text_question(self, field_name, question): |
95 | | - q = Question(question) |
96 | | - self._questions[field_name] = q |
97 | | - |
98 | | - def add_radio_question(self, field_name, question, answers): |
99 | | - q = RadioQuestion(question, answers) |
100 | | - self._questions[field_name] = q |
101 | | - |
102 | | - def get_widgets_list(self): |
103 | | - return [question.widget for question in self._questions.values()] |
104 | | - |
105 | | - def get_json(self): |
106 | | - return {field_name: question.answer |
107 | | - for field_name, question in self._questions.items()} |
108 | | - |
109 | | - |
110 | | -questions = Questions() |
111 | | -questions.add_text_question("name", u"Name: ") |
112 | | -questions.add_text_question("repoName", u"Repository name: ") |
113 | | -questions.add_text_question("repoUrl", u"Repository URL: ") |
114 | | -questions.add_text_question("api_key", u"apiKey: ") |
115 | | - |
116 | | -style = Style.from_dict({ |
117 | | - u"background": u"blue", |
118 | | -}) |
119 | | - |
120 | | - |
121 | | -class DialogLogger(object): |
122 | | - def log(self, msg): |
123 | | - layout = get_app().layout |
124 | | - dialog = Dialog(body=Label(text=msg)) |
125 | | - layout.container.floats.append( |
126 | | - Float(content=dialog) |
127 | | - ) |
128 | | - |
129 | | - def log_error_response(self, data): |
130 | | - error_str = data.get("error") |
131 | | - details = data.get("details") |
132 | | - message = data.get("message") |
133 | | - |
134 | | - if not any((error_str, details, message)): |
135 | | - raise ValueError("No error messages found") |
136 | | - |
137 | | - if error_str: |
138 | | - try: |
139 | | - self.error(error_str["message"]) |
140 | | - except (KeyError, TypeError): |
141 | | - self.error(str(error_str)) |
142 | | - |
143 | | - if details: |
144 | | - if isinstance(details, dict): |
145 | | - for key, val in details.items(): |
146 | | - if isinstance(val, six.string_types): |
147 | | - val = [val] |
148 | | - |
149 | | - for v in val: |
150 | | - msg = "{}: {}".format(key, str(v)) |
151 | | - self.error(msg) |
152 | | - else: |
153 | | - self.error(details) |
154 | | - |
155 | | - if message: |
156 | | - self.error(str(message)) |
157 | | - |
158 | | - |
159 | | -def accept_create(): |
160 | | - project = questions.get_json() |
161 | | - api_key = project.pop("api_key", None) |
162 | | - common.del_if_value_is_none(project) |
163 | | - |
164 | | - projects_api = client.API(config.CONFIG_HOST, api_key=api_key) |
165 | | - command = projects_commands.CreateProjectCommand(api=projects_api, logger_=DialogLogger()) |
166 | | - command.execute(project) |
167 | | - get_app().exit() |
168 | | - |
169 | | - |
170 | | -def accept_exit(): |
171 | | - get_app().exit() |
172 | | - |
173 | | - |
174 | | -create_button = Button(u"Create", handler=accept_create) |
175 | | -exit_button = Button(u"Exit", handler=accept_exit) |
176 | | - |
177 | | -question_widgets = [ |
178 | | - Frame(body=Label(text=u"Create new job")), |
179 | | - |
180 | | -] |
181 | | -question_widgets += questions.get_widgets_list() |
182 | | -question_widgets.append(Box(VSplit([create_button, exit_button]))) |
183 | | - |
184 | | -# float_container = |
185 | | -# root_container = HSplit( |
186 | | -# question_widgets, |
187 | | -# # style=u"grey", |
188 | | -# ) |
189 | 5 |
|
| 6 | +def run_create_project_wizard(): |
| 7 | + w = wizard.Wizard(projects_commands.CreateProjectCommand, u"Create new project") |
| 8 | + w.add_text_questions(("name", u"Name: "), |
| 9 | + ("repoName", u"Repository name: "), |
| 10 | + ("repoUrl", u"Repository URL: "), |
| 11 | + ("api_key", u"apiKey: "), ) |
190 | 12 |
|
191 | | -root_container = FloatContainer(HSplit(question_widgets), []) |
| 13 | + root_container = w.get_layout() |
192 | 14 |
|
193 | | -application = Application( |
194 | | - full_screen=True, |
195 | | - layout=Layout(root_container, ), |
196 | | - enable_page_navigation_bindings=True, |
197 | | - key_bindings=bindings, |
198 | | - style=style, |
199 | | - mouse_support=True, |
200 | | -) |
| 15 | + application = get_application(root_container) |
201 | 16 |
|
202 | | -if __name__ == '__main__': |
203 | 17 | application.run() |
0 commit comments