diff --git a/metomi/rose/config_editor/main.py b/metomi/rose/config_editor/main.py index 07a927f4b..6836b465c 100644 --- a/metomi/rose/config_editor/main.py +++ b/metomi/rose/config_editor/main.py @@ -24,7 +24,7 @@ MainController - driver for loading and central coordination. """ - +import threading import cProfile import os import pstats @@ -130,7 +130,7 @@ def __init__(self, config_directory=None, config_objs=None, self.metadata_off = metadata_off if opt_meta_paths is None: opt_meta_paths = [] - + print(2) # Set page variable 'verbosity' defaults. self.page_var_show_modes = { metomi.rose.config_editor.SHOW_MODE_CUSTOM_DESCRIPTION: @@ -195,7 +195,7 @@ def __init__(self, config_directory=None, config_objs=None, self.reporter, self.tree_trigger_update )) - + print(3) self.mainwindow = metomi.rose.config_editor.window.MainWindow() self.section_ops = metomi.rose.config_editor.ops.section.SectionOperations( @@ -229,7 +229,7 @@ def __init__(self, config_directory=None, config_objs=None, self.update_ns_sub_data, self.reload_namespace_tree ) - + print(4) # Add in the main menu bar and tool bar handler. self.main_handle = metomi.rose.config_editor.menu.MainMenuHandler( self.data, self.util, self.reporter, @@ -274,12 +274,14 @@ def __init__(self, config_directory=None, config_objs=None, config_obj_type_dict=config_obj_types, load_all_apps=load_all_apps, load_no_apps=load_no_apps) - + print(str(threading.get_ident())+"5") + print(metomi.rose.config_editor.EVENT_LOAD_STATUSES.format( + self.data.top_level_name)) self.reporter.report_load_event( metomi.rose.config_editor.EVENT_LOAD_STATUSES.format( self.data.top_level_name) ) - + print(5.1) if not self.is_pluggable: self.generate_toolbar() self.generate_menubar() @@ -287,11 +289,12 @@ def __init__(self, config_directory=None, config_objs=None, self.generate_status_bar() # Create notebook (tabbed container) and connect signals. self.notebook = metomi.rose.gtk.util.Notebook() - + print(5.2) self.updater.nav_panel = getattr(self, "nav_panel", None) - + print(6) # Create the main panel with the menu, toolbar, tree panel, notebook. if not self.is_pluggable: + print(7) self.mainwindow.load(name=self.data.top_level_name, menu=self.top_menu, accelerators=self.menubar.accelerators, @@ -301,6 +304,7 @@ def __init__(self, config_directory=None, config_objs=None, notebook=self.notebook, page_change_func=self.handle_page_change, save_func=self.save_to_file) + print(8) self.mainwindow.window.connect('destroy', self.main_handle.destroy) self.mainwindow.window.connect('delete-event', self.main_handle.destroy) @@ -1870,6 +1874,7 @@ def spawn_window(config_directory_path=None, debug_mode=False, title = config_directory_path.split("/")[-1] splash_screen = metomi.rose.gtk.splash.SplashScreenProcess(logo, title, number_of_events) + print("We are now here.") try: ctrl = MainController(config_directory_path, load_updater=splash_screen, @@ -1881,7 +1886,7 @@ def spawn_window(config_directory_path=None, debug_mode=False, except BaseException: splash_screen.stop() raise - + print("1-------") # open up any initial_namespaces the user has provided us with if initial_namespaces: # if the namespace ends with a / remove it @@ -1920,7 +1925,9 @@ def spawn_window(config_directory_path=None, debug_mode=False, True, "main") Gtk.Settings.get_default().set_long_property("gtk-menu-images", True, "main") + print("At the end of spawn window") splash_screen.stop() + print("After splash stop") Gtk.main() diff --git a/metomi/rose/config_editor/status.py b/metomi/rose/config_editor/status.py index 1b9e828fe..04b435093 100644 --- a/metomi/rose/config_editor/status.py +++ b/metomi/rose/config_editor/status.py @@ -26,6 +26,8 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk +import threading + import metomi.rose.config import metomi.rose.config_editor import metomi.rose.gtk.console @@ -55,6 +57,7 @@ def __init__(self, load_updater, status_bar_update_func): def event_handler(self, message, kind=None, level=None, prefix=None, clip=None): """Handle a message or event.""" + print(1000) message_kwargs = {} if isinstance(message, metomi.rose.reporter.Event): if kind is None: @@ -63,7 +66,11 @@ def event_handler(self, message, kind=None, level=None, prefix=None, level = message.level message_kwargs = message.kwargs if kind == self.EVENT_KIND_LOAD and not self._no_load: - return self._load_updater.update(str(message), **message_kwargs) + print(str(threading.get_ident())+" 1001") + ret = self._load_updater.update(str(message), **message_kwargs) + print(str(threading.get_ident())+" 1001---") + return ret + print(1002) return self._status_bar_update_func(message, kind, level) def report_load_event( @@ -73,7 +80,9 @@ def report_load_event( kind=self.EVENT_KIND_LOAD, no_progress=no_progress, new_total_events=new_total_events) + print("Status 1") self.report(event) + print("Status 1-1") def set_no_load(self): self._no_load = True diff --git a/metomi/rose/gtk/splash.py b/metomi/rose/gtk/splash.py index 2bbc9d130..91354f4c6 100755 --- a/metomi/rose/gtk/splash.py +++ b/metomi/rose/gtk/splash.py @@ -68,8 +68,8 @@ def __init__(self, logo_path, title, total_number_of_events): image.show() image_hbox = Gtk.HBox() image_hbox.show() - image_hbox.pack_start(image, expand=False, fill=True) - main_vbox.pack_start(image_hbox, expand=False, fill=True) + image_hbox.pack_start(image, expand=False, fill=True, padding=0) + main_vbox.pack_start(image_hbox, expand=False, fill=True, padding=0) self._is_progress_bar_pulsing = False self._progress_fraction = 0.0 self.progress_bar = Gtk.ProgressBar() @@ -94,6 +94,7 @@ def __init__(self, logo_path, title, total_number_of_events): def update(self, event, no_progress=False, new_total_events=None): """Show text corresponding to an event.""" + #print(str(threading.get_ident())+"update") text = str(event) if new_total_events is not None: self.total_number_of_events = new_total_events @@ -107,22 +108,24 @@ def update(self, event, no_progress=False, new_total_events=None): else: fraction = min( [1.0, self.event_count / self.total_number_of_events]) + #print(str(threading.get_ident())+"update 2") self._stop_pulse() - + #print(str(threading.get_ident())+"update 3") if not no_progress: GObject.idle_add(self.progress_bar.set_fraction, fraction) self._progress_fraction = fraction - + #print(str(threading.get_ident())+"update 4") self.progress_bar.set_text(text) self._progress_message = text GObject.timeout_add(self.TIME_IDLE_BEFORE_PULSE, self._start_pulse, fraction, text) - + #print(str(threading.get_ident())+"update 5") if fraction == 1.0 and not no_progress: GObject.timeout_add(self.TIME_WAIT_FINISH, self.finish) - + #print(str(threading.get_ident())+"update 6") while Gtk.events_pending(): Gtk.main_iteration() + #print(str(threading.get_ident())+"update 7") def _start_pulse(self, idle_fraction, idle_message): """Start the progress bar pulsing (moving side-to-side).""" @@ -195,18 +198,25 @@ def update(self, *args, **kwargs): return self._update_buffered(*args, **kwargs) self._flush_buffer() json_text = json.dumps({"args": args, "kwargs": kwargs}) + #print(str(threading.get_ident())+"splash L201") + #print(str(threading.get_ident())+json_text) self._communicate(json_text) def _communicate(self, json_text): + # breakpoint() while True: + #print(str(threading.get_ident())+"COMMUNICATING") + #print(str(threading.get_ident())+json_text) try: # what to do with this - got a ValueError not IOError # because the file end was reached - self.start() - self.process.communicate(input=(json_text + "\n").encode()) + # self.start() + self.process.stdin.write((json_text + "\n").encode()) + #print(str(threading.get_ident())+"COMMUNICATING AHHHHHHHHHH") except IOError: + #print(str(threading.get_ident())+"aghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh") self.start() - self.process.communicate(input=(json_text + "\n").encode()) + self.process.stdin.write((json_text + "\n").encode()) else: break @@ -228,14 +238,21 @@ def _update_buffered(self, *args, **kwargs): __call__ = update def start(self): - self.process = Popen(" ".join(["rose launch-splash-screen"] + list(self.args)), shell=True, stdin=PIPE) + #print(str(threading.get_ident())+"STARTING------------------------------------") + self.process = Popen(["rose", "launch-splash-screen"] + list(self.args), stdin=PIPE) def stop(self): + print("Inside splash stop") if self.process is not None and not self.process.stdin.closed: try: - self.process.communicate(input=json.dumps("stop") + "\n") + print("Inside splash stop try") + #print(str(threading.get_ident())+" STOPPING------------------------------------") + print((json.dumps("stop") + "\n")) + self.process.stdin.write((json.dumps("stop") + "\n").encode()) + print("Inside splash stop try - completed FINE") except IOError: pass + # self.process.kill() self.process = None @@ -251,28 +268,51 @@ def __init__(self, window, stop_event, stdin): def run(self): """Loop over time and wait for stdin lines.""" + #print(str(threading.get_ident())+"Update 100") + # breakpoint() GObject.timeout_add(1000, self._check_splash_screen_alive) while not self.stop_event.is_set(): time.sleep(0.005) if self.stop_event.is_set(): + #print(str(threading.get_ident())+" 123") return False try: + print(str(threading.get_ident())+" std_line") stdin_line = self.stdin.readline() + print(stdin_line) + # if not stdin_line: + # continue + #print(str(threading.get_ident())+"stdin_line") except IOError: continue + # if len(stdin_line) == 0: + # #print(str(threading.get_ident())+"HIT HIT HTO") + # # update_input = "stop" + # # self._stop() + # continue try: + # #print(str(threading.get_ident())+12345) update_input = json.loads(stdin_line.strip()) + print(str(threading.get_ident())+" " +str(update_input)) + # #print(str(threading.get_ident())+repr(update_input)) + # #print(str(threading.get_ident())+len(update_input)) except ValueError: continue + # if len(stdin_line) == 0: + # update_input = "stop" if update_input == "stop": + print(str(threading.get_ident())+" stop message received") self._stop() continue GObject.idle_add(self._update_splash_screen, update_input) - + #print(str(threading.get_ident())+" Update 1001") + def _stop(self): + print(str(threading.get_ident())+" Inside _stop in splash") self.stop_event.set() try: Gtk.main_quit() + print(str(threading.get_ident())+" Inside _stop in splash - splash was quit") except RuntimeError: # This can result from gtk having already quit. pass @@ -286,6 +326,7 @@ def _check_splash_screen_alive(self): def _update_splash_screen(self, update_input): """Update the splash screen with info extracted from stdin.""" + #print(str(threading.get_ident())+" _update_splash_screen") self.window.update(*update_input["args"], **update_input["kwargs"]) return False @@ -303,6 +344,7 @@ def main(argv=sys.argv): except KeyboardInterrupt: pass finally: + "FINALLY SPLASH +++++++++++++++++++++++++++++++++++++++++++++++++++++++++" stop_event.set() update_thread.join() diff --git a/metomi/rose/macro.py b/metomi/rose/macro.py index 9cd8722e1..a09d5bd40 100644 --- a/metomi/rose/macro.py +++ b/metomi/rose/macro.py @@ -399,11 +399,10 @@ def _get_config_sections(self, config_data): if "" not in sections: sections.append("") else: - for key in set( - config_data["sections"].keys() - + config_data["variables"].keys() - ): - sections.append(key) + sections = list(set( + list(config_data["sections"].keys()) + + list(config_data["variables"].keys()) + )) return sections def _get_config_section_options(self, config_data, section): diff --git a/metomi/rose/reporter.py b/metomi/rose/reporter.py index a2a4df8c9..6527e679a 100644 --- a/metomi/rose/reporter.py +++ b/metomi/rose/reporter.py @@ -135,11 +135,21 @@ def report(self, message, kind=None, level=None, prefix=None, clip=None): arguments and return its result instead. """ + print("reporting 1") if isinstance(message, bytes): message = message.decode() + print("reporting 2") if callable(self.event_handler): - return self.event_handler(message, kind, level, prefix, clip) - + print("reporting 3") + print(message) + print(kind) + print(level) + print(prefix) + print(clip) + ret = self.event_handler(message, kind, level, prefix, clip) + print("Reporter after ret L150") + return ret + print("reporting") if isinstance(message, Event): if kind is None: kind = message.kind