From 3f778f87c8675b3c4e05fd072fe03df8a35ad4f1 Mon Sep 17 00:00:00 2001 From: lxnay Date: Sun, 5 Oct 2008 18:00:41 +0000 Subject: [PATCH] Entropy/Repository Manager: - enable basic commands interactivity (half done) testing git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@2473 cd1c1023-2f26-0410-ae45-c471fc1f0318 --- libraries/entropy.py | 135 ++++++++++++++--- libraries/managerTools.py | 298 -------------------------------------- 2 files changed, 117 insertions(+), 316 deletions(-) delete mode 100644 libraries/managerTools.py diff --git a/libraries/entropy.py b/libraries/entropy.py index 2d7c3ae5b..3085b664c 100644 --- a/libraries/entropy.py +++ b/libraries/entropy.py @@ -21143,10 +21143,11 @@ class SystemManagerExecutorServerRepositoryInterface: cmd = ["emerge", "--sync"] try: - p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err) + p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id)) self._set_processing_pid(queue_id, p.pid) rc = p.wait() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") stdout_err.flush() stdout_err.close() @@ -21175,7 +21176,8 @@ class SystemManagerExecutorServerRepositoryInterface: if cflags: cmd += ['export CFLAGS="']+custom_use.strip().split()+['"','&&'] cmd += [etpConst['spm']['exec']]+atoms - if pretend: cmd.append(etpConst['spm']['pretend_cmd']) + if pretend: + cmd.append(etpConst['spm']['pretend_cmd']) if verbose: cmd.append(etpConst['spm']['verbose_cmd']) if oneshot: @@ -21193,10 +21195,11 @@ class SystemManagerExecutorServerRepositoryInterface: stdout_err.flush() try: - p = self.subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, shell = True) + p = self.subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True) self._set_processing_pid(queue_id, p.pid) rc = p.wait() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") stdout_err.flush() stdout_err.close() @@ -21224,10 +21227,11 @@ class SystemManagerExecutorServerRepositoryInterface: stdout_err.flush() try: - p = self.subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, shell = True) + p = self.subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True) self._set_processing_pid(queue_id, p.pid) rc = p.wait() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") stdout_err.flush() stdout_err.close() @@ -21349,10 +21353,11 @@ class SystemManagerExecutorServerRepositoryInterface: stdout_err.flush() try: - p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err) + p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id)) self._set_processing_pid(queue_id, p.pid) rc = p.wait() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") stdout_err.flush() stdout_err.close() @@ -21375,10 +21380,11 @@ class SystemManagerExecutorServerRepositoryInterface: stdout_err.flush() try: - p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, shell = True) + p = self.subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True) self._set_processing_pid(queue_id, p.pid) rc = p.wait() finally: + stdout_err.write('Stdin: %s\n' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") stdout_err.flush() stdout_err.close() @@ -21410,6 +21416,7 @@ class SystemManagerExecutorServerRepositoryInterface: do_copy = do_copy ) finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") self.SystemManagerExecutor.SystemInterface.Entropy.updateProgress = old_updprogress stdout_err.flush() @@ -21462,6 +21469,7 @@ class SystemManagerExecutorServerRepositoryInterface: dbconn.closeDB() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") self.SystemManagerExecutor.SystemInterface.Entropy.updateProgress = old_updprogress stdout_err.flush() @@ -21567,6 +21575,7 @@ class SystemManagerExecutorServerRepositoryInterface: self.entropyTools.printTraceback(f = stdout_err) return False,str(e) finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21598,6 +21607,7 @@ class SystemManagerExecutorServerRepositoryInterface: self.entropyTools.printTraceback(f = stdout_err) return False,str(e) finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21629,6 +21639,7 @@ class SystemManagerExecutorServerRepositoryInterface: self.entropyTools.printTraceback(f = stdout_err) return False,str(e) finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21664,6 +21675,7 @@ class SystemManagerExecutorServerRepositoryInterface: else: data = Entropy.verify_remote_packages([], ask = False, repo = repoid) finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21693,6 +21705,7 @@ class SystemManagerExecutorServerRepositoryInterface: dbconn = Entropy.openServerDatabase(repo = repoid, do_cache = False, ask_treeupdates = False, read_only = True) dbconn.closeDB() finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21775,6 +21788,7 @@ class SystemManagerExecutorServerRepositoryInterface: finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21886,6 +21900,7 @@ class SystemManagerExecutorServerRepositoryInterface: finally: + stdout_err.write('\n\n Stdin: %s' % (self._get_stdin(queue_id),)) stdout_err.write("\n### Done ###\n") Entropy.updateProgress = old_updprogress Entropy.ClientService.updateProgress = old_client_updprogress @@ -21907,6 +21922,12 @@ class SystemManagerExecutorServerRepositoryInterface: data[myid] = self.SystemManagerExecutor.SystemInterface.Entropy.SpmService.get_glsa_id_information(myid) return True,data + def _get_stdin(self, queue_id): + mystdin = None + std_data = self.SystemManagerExecutor.SystemInterface.ManagerStdInOut.get(queue_id) + if std_data != None: mystdin = std_data[0] + return mystdin + def _file_updateProgress(self, f, *myargs, **mykwargs): f.flush() @@ -22345,7 +22366,7 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): 'cflags': cflags, } - queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'compile_atoms', [atoms[:]], add_dict.copy(), False, False) + queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'compile_atoms', [atoms[:]], add_dict.copy(), False, False, interactive = True) if queue_id < 0: return False, queue_id return True, queue_id @@ -22387,7 +22408,7 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): 'nocolor': nocolor, } - queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'spm_remove_atoms', [atoms[:]], add_dict.copy(), False, False) + queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'spm_remove_atoms', [atoms[:]], add_dict.copy(), False, False, interactive = True) if queue_id < 0: return False, queue_id return True, queue_id @@ -22494,7 +22515,7 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): gid = userdata.get('gid') command = ' '.join(myargs) - queue_id = self.HostInterface.add_to_queue(cmd, command, uid, gid, 'run_custom_shell_command', [command], {}, False, False) + queue_id = self.HostInterface.add_to_queue(cmd, command, uid, gid, 'run_custom_shell_command', [command], {}, False, False, interactive = True) if queue_id < 0: return False, queue_id return True, queue_id @@ -22677,7 +22698,7 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): uid = userdata.get('uid') gid = userdata.get('gid') - queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'run_entropy_treeupdates', [myargs[0]], {}, False, False) + queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'run_entropy_treeupdates', [myargs[0]], {}, False, False, interactive = True) if queue_id < 0: return False, queue_id return True, queue_id @@ -22709,7 +22730,7 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): uid = userdata.get('uid') gid = userdata.get('gid') - queue_id = self.HostInterface.add_to_queue(cmd, '', uid, gid, 'run_entropy_mirror_updates', [mydict], {}, False, False) + queue_id = self.HostInterface.add_to_queue(cmd, '', uid, gid, 'run_entropy_mirror_updates', [mydict], {}, False, False, interactive = True) if queue_id < 0: return False, queue_id return True, queue_id @@ -22750,7 +22771,11 @@ class SystemManagerRepositoryCommands(SocketCommandsSkel): uid = userdata.get('uid') gid = userdata.get('gid') - queue_id = self.HostInterface.add_to_queue(cmd, ' '.join(myargs), uid, gid, 'run_entropy_database_updates', [to_add,to_remove,to_inject], {}, False, True) + queue_id = self.HostInterface.add_to_queue( + cmd, ' '.join(myargs), uid, gid, + 'run_entropy_database_updates', [to_add,to_remove,to_inject], + {}, False, True, interactive = True + ) if queue_id < 0: return False, queue_id return True, queue_id @@ -22871,7 +22896,10 @@ class SystemManagerServerInterface(SocketHostInterface): def __init__(self, HostInterface): SocketCommandsSkel.__init__(self, HostInterface, inst_name = "systemsrv") - self.raw_commands = ['systemsrv:add_to_pinboard'] + self.raw_commands = [ + 'systemsrv:add_to_pinboard', + 'systemsrv:write_to_running_command_pipe' + ] self.valid_commands = { 'systemsrv:get_queue': { @@ -22994,6 +23022,16 @@ class SystemManagerServerInterface(SocketHostInterface): 'syntax': " systemsrv:set_pinboard_items_done <...> ", 'from': str(self), }, + 'systemsrv:write_to_running_command_pipe': { + 'auth': True, + 'built_in': False, + 'cb': self.docmd_write_to_running_command_pipe, + 'args': ["myargs"], + 'as_user': False, + 'desc': "write text to stdin of a running command", + 'syntax': " systemsrv:write_to_running_command_pipe ", + 'from': str(self), + }, } def docmd_get_queue(self, myargs): @@ -23207,6 +23245,37 @@ class SystemManagerServerInterface(SocketHostInterface): self.HostInterface.set_pinboard_item_status(pinboard_id, status) return True,'ok' + def docmd_write_to_running_command_pipe(self, myargs): + + if len(myargs) < 2: + return False, 'wrong arguments' + + try: + queue_id = int(myargs[0]) + except ValueError: + return False,'invalid queue id' + + txt = ' '.join(myargs[1:]) + item, key = self.HostInterface.get_item_by_queue_id(queue_id) + if key != self.HostInterface.processing_queue_keys: + return False,'not running' + mypipe = self.HostInterface.ManagerQueueStdInOut.get(queue_id) + if mypipe == None: + return False,'pipe not available' + try: + w_fd = mypipe[1] + except (IndexError, ValueError,): + return False,'pipe vanished' + if not isinstance(w_fd,int): + return False,'stdout fd not an int' + try: + os.write(w_fd,txt) + except OSError, e: + return False,'OSError: %s' % (e,) + + return True,'ok' + + class FakeServiceInterface: def __init__(self, *args, **kwargs): pass @@ -23232,7 +23301,7 @@ class SystemManagerServerInterface(SocketHostInterface): STDOUT_STORAGE_DIR = os.path.join(etpConst['dumpstoragedir'],'system_manager_stdout') def __init__(self, EntropyInterface, do_ssl = False, stdout_logging = True, fork_requests = False, entropy_interface_kwargs = {}, **kwargs): - nocolor() + #nocolor() self.queue_loaded = False import entropyTools, dumpTools, copy self.entropyTools, self.dumpTools, self.copy = entropyTools, dumpTools, copy @@ -23267,6 +23336,7 @@ class SystemManagerServerInterface(SocketHostInterface): self.removable_queue_keys = ['processed','errored','queue'] self.processing_queue_keys = ['processing'] self.dict_queue_keys = ['queue','processing','processed','errored'] + self.ManagerQueueStdInOut = {} self.ManagerQueue = { 'queue': {}, 'queue_order': [], @@ -23446,7 +23516,7 @@ class SystemManagerServerInterface(SocketHostInterface): return True - def add_to_queue(self, command_name, command_text, user_id, group_id, function, args, kwargs, do_parallel, extended_result): + def add_to_queue(self, command_name, command_text, user_id, group_id, function, args, kwargs, do_parallel, extended_result, interactive = False): if function not in self.SystemExecutor.available_commands: return -1 @@ -23454,6 +23524,8 @@ class SystemManagerServerInterface(SocketHostInterface): self.queue_lock_acquire() try: queue_id = self.generate_unique_queue_id() + if interactive: + self.ManagerQueueStdInOut[queue_id] = os.pipe() myqueue_dict = { 'queue_id': queue_id, 'command_name': command_name, @@ -23469,6 +23541,7 @@ class SystemManagerServerInterface(SocketHostInterface): 'kill': False, 'processing_pid': None, 'do_parallel': do_parallel, + 'interactive': False, } if extended_result: myqueue_dict['extended_result'] = None @@ -23493,7 +23566,7 @@ class SystemManagerServerInterface(SocketHostInterface): except KeyError: continue if item: - self.flush_item(item) + self.flush_item(item, queue_id) if queue_id in self.ManagerQueue[key+"_order"]: self.ManagerQueue[key+"_order"].remove(queue_id) removed = True @@ -23526,14 +23599,19 @@ class SystemManagerServerInterface(SocketHostInterface): finally: self.queue_lock_release() - def flush_item(self, item): + def flush_item(self, item, queue_id): if not isinstance(item,dict): return False if item.has_key('stdout'): stdout = item['stdout'] if (os.path.isfile(stdout) and os.access(stdout,os.W_OK)): os.remove(stdout) - return True + if item.has_key('interactive'): + if item['interactive'] and (queue_id in self.ManagerQueueStdInOut): + stdin, stdout = self.ManagerQueueStdInOut.pop(queue_id) + os.close(stdin) + os.close(stdout) + return True def assign_unique_stdout_file(self, queue_id): stdout = os.path.join(self.STDOUT_STORAGE_DIR,"%d.%s" % (queue_id,"stdout",)) @@ -23826,6 +23904,15 @@ class SystemManagerClientCommands(EntropySocketClientCommands): ) return self.do_generic_handler(cmd, session_id) + def write_to_running_command_pipe(self, session_id, queue_id, txt): + cmd = "%s %s %s %s" % ( + session_id, + 'systemsrv:write_to_running_command_pipe', + queue_id, + txt, + ) + return self.do_generic_handler(cmd, session_id) + class SystemManagerRepositoryClientCommands(SystemManagerClientCommands): import dumpTools @@ -24216,6 +24303,15 @@ class SystemManagerMethodsInterface: 'call': self.set_pinboard_items_done, 'private': True, }, + 'write_to_running_command_pipe': { + 'desc': _("Write to a remote running command stdin"), + 'params': [ + ('queue_id',int,_('Queue Identifier'),True,), + ('txt',basestring,_('Text'),True,), + ], + 'call': self.write_to_running_command_pipe, + 'private': True, + }, } def get_available_commands(self): @@ -24257,6 +24353,9 @@ class SystemManagerMethodsInterface: def set_pinboard_items_done(self, pinboard_ids, done_status): return self.Manager.do_cmd(True, "set_pinboard_items_done", [pinboard_ids,done_status], {}) + def write_to_running_command_pipe(self, queue_id, txt): + return self.Manager.do_cmd(True, "write_to_running_command_pipe", [queue_id, txt], {}) + class SystemManagerRepositoryMethodsInterface(SystemManagerMethodsInterface): def __init__(self, *args, **kwargs): diff --git a/libraries/managerTools.py b/libraries/managerTools.py deleted file mode 100644 index 25e92f78c..000000000 --- a/libraries/managerTools.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/python -''' - # DESCRIPTION: - # enzyme helper classes - - Copyright (C) http://excess.org/urwid - Thanks to Urwid developers, stuff taken from here too: - http://excess.org/urwid/browser/urwid/trunk/dialog.py?format=txt - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' -import urwid -from entropyConstants import * -from entropy_i18n import _ - -class ManagerSettings: - - def __init__(self): - self.Widgets = None - self.process_spawned = False - self.menu_enabled = False - self.last_rc = None - self.output_buffer = '' - self.screen = None - self.mainFrame = None - self.mainBody = None - self.menuBar = None - self.statusBar = None - self.programWidget = None - self.outputWidget = None - self.pinboardWidget = None - self.output = None - self.output_row = 1 - self.max_x, self.max_y = 0,0 - self.welcome_text = _("(CTRL+E Menu | CTRL+X Exit)") - self.header_txt = '' - self.inFocus = 0 - self.focusOptions = [0,1] - self.focusInfo = { - 0: "Application", - 1: "Terminal" - } - self.auth_data = {} - self.menu_keys_calls = {} - - -class PasswordEdit(urwid.Edit): - - def __init__(self, *args, **kwargs): - urwid.Edit.__init__(self, *args, **kwargs) - self._clean_edit_text = '' - - def set_edit_text(self, text): - """Set the edit text for this widget.""" - self.highlight = None - self._clean_edit_text = text - text = '*'*len(text) - self.edit_text = text - if self.edit_pos > len(text): - self.edit_pos = len(text) - self._invalidate() - - def insert_text(self, text): - """Insert text at the cursor position and update cursor.""" - p = self.edit_pos - self.set_edit_text( self._clean_edit_text[:p] + text + - self._clean_edit_text[p:] ) - self.set_edit_pos( self.edit_pos + len(text)) - - def get_edit_text(self): - return self._clean_edit_text - -class SimpleWidgets: - - class QuestionWidget(urwid.WidgetWrap): - """ - Creates a BoxWidget that displays a message - - Attributes: - - b_pressed -- Contains the label of the last button pressed or None if no - button has been pressed. - edit_text -- After a button is pressed, this contains the text the user - has entered in the edit field - """ - - b_pressed = None - edit_text = None - _edit_widget = None - _mode = None - - def __init__(self, msg, buttons, attr, width, height, body): - """ - msg -- content of the message widget, one of: - plain string -- string is displayed - (attr, markup2) -- markup2 is given attribute attr - [markupA, markupB, ... ] -- list items joined together - buttons -- a list of strings with the button labels - attr -- a tuple (background, button, active_button) of attributes - width -- width of the message widget - height -- height of the message widget - body -- widget displayed beneath the message widget - """ - - self._blank = urwid.Text("") - #Text widget containing the message: - msg_widget = urwid.Padding(urwid.Text(msg), 'center', width - 4) - - #GridFlow widget containing all the buttons: - button_widgets = [] - - for button in buttons: - button_widgets.append(urwid.AttrWrap(urwid.Button(button, self._action), attr[1], attr[2])) - - button_grid = urwid.GridFlow(button_widgets, 12, 2, 1, 'center') - - #Combine message widget and button widget: - widget_list = [msg_widget, self._blank, button_grid] - self._combined = urwid.AttrWrap(urwid.Filler(urwid.Pile(widget_list, 2)), attr[0]) - - #Place the dialog widget on top of body: - overlay = urwid.Overlay(self._combined, body, 'center', width, 'middle', height) - - urwid.WidgetWrap.__init__(self, overlay) - - def _action(self, button): - """ - Function called when a button is pressed. - Should not be called manually. - """ - - self.b_pressed = button.get_label() - if self._edit_widget: - self.edit_text = self._edit_widget.get_edit_text() - - class MenuWidget(urwid.WidgetWrap): - - class SelText(urwid.Text): - """ - A selectable text widget. See urwid.Text. - """ - - def selectable(self): - return True - - def keypress(self, size, key): - """ - Don't handle any keys. - """ - return key - - """ - Creates a popup menu on top of another BoxWidget. - - Attributes: - - selected -- Contains the item the user has selected by pressing , - or None if nothing has been selected. - """ - - selected = None - - def __init__(self, menu_list, attr, pos, body): - """ - menu_list -- a list of strings with the menu entries - attr -- a tuple (background, active_item) of attributes - pos -- a tuple (x, y), position of the menu widget - body -- widget displayed beneath the message widget - """ - - content = [urwid.AttrWrap(self.SelText(" " + w), None, attr[1]) - for w in menu_list] - - #Calculate width and height of the menu widget: - height = len(menu_list) - width = 0 - for entry in menu_list: - if len(entry) > width: - width = len(entry) - - #Create the ListBox widget and put it on top of body: - self._listbox = urwid.AttrWrap(urwid.ListBox(content), attr[0]) - overlay = urwid.Overlay(self._listbox, body, ('fixed left', pos[0]), - width + 2, ('fixed top', pos[1]), height) - - urwid.WidgetWrap.__init__(self, overlay) - - - def keypress(self, size, key): - """ - key selects an item, other keys will be passed to - the ListBox widget. - """ - - if key == "enter": - (widget, foo) = self._listbox.get_focus() - (text, foo) = widget.get_text() - self.selected = text[1:] #Get rid of the leading space... - else: - return self._listbox.keypress(size, key) - - class InputDialogWidget(urwid.WidgetWrap): - - b_pressed = None - def __init__(self, title, input_parameters, attr, width, body, cancel = True): - - self.labels = { - _('Ok'): 'ok', - _('Cancel'): 'cancel', - } - height = 6 - self.button_values = ['ok','cancel'] - self.input_text_is_valid = False - self.input_data = {} - self.edit_widgets = [] - self.input_parameters = input_parameters[:] - self.identifiers = {} - self.do_cancel = cancel - for identifier,widget_text,callback, password in self.input_parameters: - if password: - myw = PasswordEdit(caption = widget_text+": ") - else: - myw = urwid.Edit(caption = widget_text+": ") - self.identifiers[identifier] = (myw,callback,widget_text,) - self.edit_widgets.append(myw) - height += 1 - - # blank line - self._blank = urwid.Text("") - self._title = urwid.Text(title) - # buttons - button_widgets = [] - button_widgets.append(urwid.AttrWrap(urwid.Button(_('Ok'), self._action), attr[1], attr[2])) - if self.do_cancel: - button_widgets.append(urwid.AttrWrap(urwid.Button(_('Cancel'), self._action), attr[1], attr[2])) - # button grid - button_grid = urwid.GridFlow(button_widgets, 12, 2, 1, 'center') - - #Combine message widget and button widget: - widget_list = [self._title,self._blank] - widget_list += self.edit_widgets - widget_list += [self._blank, button_grid] - - self._combined = urwid.Filler(urwid.Pile(widget_list, 2)) - self._combined = urwid.Padding(self._combined, 'center', width - 4) - self._combined = urwid.AttrWrap(self._combined, attr[0]) - - #Place the dialog widget on top of body: - overlay = urwid.Overlay(self._combined, body, 'center', width+4, 'middle', height+1) - urwid.WidgetWrap.__init__(self, overlay) - - def _action(self, button): - """ - Function called when a button is pressed. - Should not be called manually. - """ - - got_valid = True - b_pressed = button.get_label() - self.b_pressed = None - # update input_data - for identifier in self.identifiers: - self.input_data[identifier] = None - myw, cb, widget_text = self.identifiers[identifier] - result = myw.get_edit_text() - valid = cb(result) - if valid: - self.input_data[identifier] = result - else: - got_valid = False - self.input_text_is_valid = got_valid - self.b_pressed = self.labels.get(b_pressed) - - def __init__(self, interface): - self.Manager = interface.Manager - self.Interface = interface - - def Dialog(self, message, options): - return self.QuestionWidget(message, options, ('menu', 'bg', 'bgf'), 30, 5, self.Manager.mainFrame) - - def InputDialog(self, title, input_parameters, show_cancel = True): - return self.InputDialogWidget(title, input_parameters, ('menu', 'bg', 'bgf'), 40, self.Manager.mainFrame, cancel = show_cancel) - - def Menu(self, options, position): - return self.MenuWidget(options, ('menu', 'menuf'), position, self.Manager.mainFrame) -