pyceo/ceo/tui/controllers/TransactionController.py

111 lines
3.7 KiB
Python

from threading import Thread
from typing import Dict, List
from ...StreamResponseHandler import StreamResponseHandler
from ...utils import http_request, generic_handle_stream_response
from .Controller import Controller
class TransactionController(Controller, StreamResponseHandler):
def __init__(self, model, app):
super().__init__(model, app)
self.op_idx = 0
self.error_messages = []
def start(self):
Thread(target=self._start_txn).start()
def _start_txn(self):
resp = http_request(
self.model.http_verb,
self.model.req_path,
**self.model.req_kwargs
)
data = generic_handle_stream_response(resp, self.model.operations, self)
self.write_extra_txn_info(data)
# to be overridden in child classes if desired
def write_extra_txn_info(self, data: List[Dict]):
pass
def _show_lines(self, lines):
num_lines = len(lines)
# Since the message_text is at the bottom of the window,
# we want to add sufficient padding to the bottom of the text
lines += [''] * max(4 - num_lines, 0)
for i, line in enumerate(lines):
if type(line) is str:
lines[i] = line + '\n'
else: # tuple (attr, text)
lines[i] = (line[0], line[1] + '\n')
self.view.message_text.set_text(lines)
def _abort(self):
for elem in self.view.right_col_elems[self.op_idx:]:
elem.set_text(('red', 'ABORTED'))
self.view.enable_next_button()
def begin(self):
pass
def handle_non_200(self, resp):
def target():
self._abort()
lines = ['An error occurred:']
if resp.headers.get('content-type') == 'application/json':
err_msg = resp.json()['error']
else:
err_msg = resp.text
lines.extend(err_msg.split('\n'))
self._show_lines(lines)
self.app.run_in_main_loop(target)
def handle_aborted(self, err_msg):
def target():
self._abort()
lines = [
'The transaction was rolled back.',
'The error was:',
'',
*err_msg.split('\n'),
]
self._show_lines(lines)
self.app.run_in_main_loop(target)
def handle_completed(self):
def target():
lines = ['Transaction successfully completed.']
if len(self.error_messages) > 0:
lines.append('There were some errors:')
for msg in self.error_messages:
lines.extend(msg.split('\n'))
self._show_lines(lines)
self.view.enable_next_button()
self.app.run_in_main_loop(target)
def handle_successful_operation(self):
def target():
self.view.right_col_elems[self.op_idx].set_text(('green', 'Done'))
self.op_idx += 1
self.app.run_in_main_loop(target)
def handle_failed_operation(self, err_msg):
def target():
self.view.right_col_elems[self.op_idx].set_text(('red', 'Failed'))
self.op_idx += 1
if err_msg is not None:
self.error_messages.append(err_msg)
self.app.run_in_main_loop(target)
def handle_skipped_operation(self):
def target():
self.view.right_col_elems[self.op_idx].set_text('Skipped')
self.op_idx += 1
self.app.run_in_main_loop(target)
def handle_unrecognized_operation(self, operation):
def target():
self.error_messages.append('Unrecognized operation: ' + operation)
self.op_idx += 1
self.app.run_in_main_loop(target)