def controller(self, mocker) -> None: # Patch these unconditionally to avoid calling in __init__ self.poll_for_events = mocker.patch(CORE + ".Model.poll_for_events") mocker.patch(CORE + ".Controller.show_loading") self.main_loop = mocker.patch(CORE + ".urwid.MainLoop", return_value=mocker.Mock()) self.config_file = "path/to/zuliprc" self.theme_name = "zt_dark" self.theme = "default" self.in_explore_mode = False self.autohide = True # FIXME Add tests for no-autohide self.notify_enabled = False self.maximum_footlinks = 3 result = Controller( self.config_file, self.maximum_footlinks, self.theme_name, self.theme, 256, self.in_explore_mode, self.autohide, self.notify_enabled, ) result.view.message_view = mocker.Mock() # set in View.__init__ result.model.server_url = SERVER_URL return result
def test_register(self, mocker): self.config_file = 'path/to/zuliprc' self.theme = 'default' controller = Controller(self.config_file, self.theme) event_types = ['message', 'update_message', 'reaction'] controller.client.register.assert_called_once_with( event_types=event_types)
def controller(self, mocker) -> None: self.config_file = 'path/to/zuliprc' self.theme = 'default' self.autohide = True # FIXME Add tests for no-autohide self.notify_enabled = False return Controller(self.config_file, self.theme, 256, self.autohide, self.notify_enabled)
def controller(self, mocker: MockerFixture) -> Controller: # Patch these unconditionally to avoid calling in __init__ self.poll_for_events = mocker.patch(MODEL + ".poll_for_events") mocker.patch(MODULE + ".Controller.show_loading") self.main_loop = mocker.patch( MODULE + ".urwid.MainLoop", return_value=mocker.Mock() ) self.config_file = "path/to/zuliprc" self.theme_name = "zt_dark" self.theme = generate_theme("zt_dark", 256) self.in_explore_mode = False self.autohide = True # FIXME Add tests for no-autohide self.notify_enabled = False self.maximum_footlinks = 3 result = Controller( config_file=self.config_file, maximum_footlinks=self.maximum_footlinks, theme_name=self.theme_name, theme=self.theme, color_depth=256, in_explore_mode=self.in_explore_mode, debug_path=None, **dict( autohide=self.autohide, notify=self.notify_enabled, ), ) result.view.message_view = mocker.Mock() # set in View.__init__ result.model.server_url = SERVER_URL return result
def main(): """ Launch Zulip Terminal. """ args = parse_args() if args.debug: save_stdout() if args.profile: import cProfile prof = cProfile.Profile() prof.enable() try: Controller(args.config_file, args.theme).main() except Exception: # A unexpected exception occurred, open the debugger in debug mode if args.debug: import pudb pudb.post_mortem() finally: if args.debug: restore_stdout() if args.profile: prof.disable() prof.dump_stats("/tmp/profile.data") print("Profile data saved to /tmp/profile.data") print("You can visualize it using e.g." "`snakeviz /tmp/profile.data`") print("\nThanks for using the Zulip-Terminal interface.\n") sys.exit(1)
def test_register_initial_desired_events(self, mocker): self.config_file = 'path/to/zuliprc' self.theme = 'default' controller = Controller(self.config_file, self.theme) event_types = [ 'message', 'update_message', 'reaction', 'typing', ] controller.client.register.assert_called_once_with( event_types=event_types, apply_markdown=True)
def controller(self, mocker) -> None: # Patch these unconditionally to avoid calling in __init__ self.poll_for_events = mocker.patch(CORE + '.Model.poll_for_events') mocker.patch(CORE + '.Controller.show_loading') self.config_file = 'path/to/zuliprc' self.theme = 'default' self.autohide = True # FIXME Add tests for no-autohide self.notify_enabled = False self.footlinks_enabled = True result = Controller(self.config_file, self.theme, 256, self.autohide, self.notify_enabled, self.footlinks_enabled) result.view.message_view = mocker.Mock() # set in View.__init__ return result
def main() -> None: """ Launch Zulip Terminal. """ args = parse_args() if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = '~/zuliprc' zterm = parse_zuliprc(zuliprc_path) if args.profile: import cProfile prof = cProfile.Profile() prof.enable() try: Controller(zuliprc_path, zterm['theme']).main() except Exception as e: if args.debug: # A unexpected exception occurred, open the debugger in debug mode import pudb pudb.post_mortem() sys.stdout.flush() traceback.print_exc(file=sys.stderr) print("Zulip Terminal has crashed!", file=sys.stderr) print("You can ask for help at:", file=sys.stderr) print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() prof.dump_stats("/tmp/profile.data") print("Profile data saved to /tmp/profile.data") print("You can visualize it using e.g." "`snakeviz /tmp/profile.data`") sys.exit(1)
def main(options: Optional[List[str]] = None) -> None: """ Launch Zulip Terminal. """ argv = options if options is not None else sys.argv[1:] args = parse_args(argv) if args.profile: import cProfile prof = cProfile.Profile() prof.enable() if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = '~/zuliprc' try: zterm = parse_zuliprc(zuliprc_path) if args.theme: theme_to_use = (args.theme, 'on command line') else: theme_to_use = zterm['theme'] valid_themes = THEMES.keys() if theme_to_use[0] not in valid_themes: print("Invalid theme '{}' was specified {}.".format(*theme_to_use)) print("The following themes are available:") for theme in valid_themes: print(" ", theme) print("Specify theme in zuliprc file or override " "using -t/--theme options on command line.") sys.exit(1) valid_autohide_settings = {'autohide', 'no_autohide'} if zterm['autohide'][0] not in valid_autohide_settings: print("Invalid autohide setting '{}' was specified {}.".format( *zterm['autohide'])) print("The following options are available:") for option in valid_autohide_settings: print(" ", option) print("Specify the autohide option in zuliprc file.") sys.exit(1) autohide_setting = (zterm['autohide'][0] == 'autohide') print("Loading with:") print(" theme '{}' specified {}.".format(*theme_to_use)) print(" autohide setting '{}' specified {}.".format( *zterm['autohide'])) Controller(zuliprc_path, THEMES[theme_to_use[0]], autohide_setting).main() except ServerConnectionFailure as e: print("\n\033[91mError connecting to Zulip server: {}.".format(e)) sys.exit(1) except Exception as e: if args.debug: # A unexpected exception occurred, open the debugger in debug mode import pudb pudb.post_mortem() sys.stdout.flush() traceback.print_exc(file=sys.stderr) print("Zulip Terminal has crashed!", file=sys.stderr) print("You can ask for help at:", file=sys.stderr) print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() prof.dump_stats("/tmp/profile.data") print("Profile data saved to /tmp/profile.data") print("You can visualize it using e.g." "`snakeviz /tmp/profile.data`") sys.exit(1)
def main(options: Optional[List[str]] = None) -> None: """ Launch Zulip Terminal. """ argv = options if options is not None else sys.argv[1:] args = parse_args(argv) set_encoding('utf-8') if args.profile: import cProfile prof = cProfile.Profile() prof.enable() if args.version: print('Zulip Terminal ' + ZT_VERSION) sys.exit(0) if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = '~/zuliprc' try: zterm = parse_zuliprc(zuliprc_path) if args.theme: theme_to_use = (args.theme, 'on command line') else: theme_to_use = zterm['theme'] available_themes = all_themes() if theme_to_use[0] not in available_themes: print("Invalid theme '{}' was specified {}.".format(*theme_to_use)) print("The following themes are available:") for theme in available_themes: print(" ", theme) print("Specify theme in zuliprc file or override " "using -t/--theme options on command line.") sys.exit(1) valid_autohide_settings = {'autohide', 'no_autohide'} if zterm['autohide'][0] not in valid_autohide_settings: print("Invalid autohide setting '{}' was specified {}.".format( *zterm['autohide'])) print("The following options are available:") for option in valid_autohide_settings: print(" ", option) print("Specify the autohide option in zuliprc file.") sys.exit(1) autohide_setting = (zterm['autohide'][0] == 'autohide') print("Loading with:") print(" theme '{}' specified {}.".format(*theme_to_use)) complete, incomplete = complete_and_incomplete_themes() if theme_to_use[0] in incomplete: print( in_color( 'yellow', " WARNING: Incomplete theme; " "results may vary!\n" " (you could try: {})".format(", ".join(complete)))) print(" autohide setting '{}' specified {}.".format( *zterm['autohide'])) Controller(zuliprc_path, THEMES[theme_to_use[0]], autohide_setting).main() except ServerConnectionFailure as e: print( in_color('red', "\nError connecting to Zulip server: {}.".format(e))) # Acts as separator between logs logging.info("\n\n" + str(e) + "\n\n") logging.exception(e) sys.exit(1) except Exception as e: logging.info("\n\n" + str(e) + "\n\n") logging.exception(e) if args.debug: sys.stdout.flush() traceback.print_exc(file=sys.stderr) run_debugger = input("Run Debugger? (y/n): ") if run_debugger in ["y", "Y", "yes"]: # Open PUDB Debuuger import pudb pudb.post_mortem() if hasattr(e, 'extra_info'): print( "\n" + in_color("red", e.extra_info), # type: ignore file=sys.stderr) print(in_color( "red", "\nZulip Terminal has crashed!" "\nPlease refer to " + LOG_FILENAME + " for full log of" " the error."), file=sys.stderr) print("You can ask for help at:", file=sys.stderr) print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() prof.dump_stats("/tmp/profile.data") print("Profile data saved to /tmp/profile.data") print("You can visualize it using e.g." "`snakeviz /tmp/profile.data`") sys.exit(1)
def main(options: Optional[List[str]] = None) -> None: """ Launch Zulip Terminal. """ argv = options if options is not None else sys.argv[1:] args = parse_args(argv) set_encoding('utf-8') if args.debug: print("NOTE: Debug mode enabled; API calls being logged to {}.".format( in_color("blue", API_CALL_LOG_FILENAME))) requests_logfile_handler = logging.FileHandler(API_CALL_LOG_FILENAME) requests_logger.addHandler(requests_logfile_handler) else: requests_logger.addHandler(logging.NullHandler()) if args.profile: import cProfile prof = cProfile.Profile() prof.enable() if args.version: print('Zulip Terminal ' + ZT_VERSION) sys.exit(0) if args.list_themes: available_themes = all_themes() print('Themes available:') for theme in available_themes: print(' {}'.format(theme)) sys.exit(0) if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = '~/zuliprc' try: zterm = parse_zuliprc(zuliprc_path) if args.autohide: zterm['autohide'] = (args.autohide, 'on command line') if args.theme: theme_to_use = (args.theme, 'on command line') else: theme_to_use = zterm['theme'] available_themes = all_themes() theme_aliases = aliased_themes() is_valid_theme = (theme_to_use[0] in available_themes or theme_to_use[0] in theme_aliases) if not is_valid_theme: print("Invalid theme '{}' was specified {}.".format(*theme_to_use)) print("The following themes are available:") for theme in available_themes: print(" ", theme) print("Specify theme in zuliprc file or override " "using -t/--theme options on command line.") sys.exit(1) if theme_to_use[0] not in available_themes: # theme must be an alias, as it is valid real_theme_name = theme_aliases[theme_to_use[0]] theme_to_use = (real_theme_name, "{} (by alias '{}')".format( theme_to_use[1], theme_to_use[0])) if args.color_depth: zterm['color-depth'] = (args.color_depth, 'on command line') color_depth = int(zterm['color-depth'][0]) print("Loading with:") print(" theme '{}' specified {}.".format(*theme_to_use)) complete, incomplete = complete_and_incomplete_themes() if theme_to_use[0] in incomplete: print( in_color( 'yellow', " WARNING: Incomplete theme; " "results may vary!\n" " (you could try: {})".format(", ".join(complete)))) print(" autohide setting '{}' specified {}.".format( *zterm['autohide'])) print(" footlinks setting '{}' specified {}.".format( *zterm['footlinks'])) print(" color depth setting '{}' specified {}.".format( *zterm['color-depth'])) # For binary settings # Specify setting in order True, False valid_settings = { 'autohide': ['autohide', 'no_autohide'], 'notify': ['enabled', 'disabled'], 'footlinks': ['enabled', 'disabled'], 'color-depth': ['1', '16', '256'] } boolean_settings = dict() # type: Dict[str, bool] for setting, valid_values in valid_settings.items(): if zterm[setting][0] not in valid_values: print("Invalid {} setting '{}' was specified {}.".format( setting, *zterm[setting])) print("The following options are available:") for option in valid_values: print(" ", option) print("Specify the {} option in zuliprc file.".format(setting)) sys.exit(1) if setting == 'color-depth': break boolean_settings[setting] = (zterm[setting][0] == valid_values[0]) if color_depth == 1: theme_data = theme_with_monochrome_added(THEMES[theme_to_use[0]]) else: theme_data = THEMES[theme_to_use[0]] Controller(zuliprc_path, theme_data, color_depth, args.explore, **boolean_settings).main() except ServerConnectionFailure as e: print( in_color('red', "\nError connecting to Zulip server: {}.".format(e))) # Acts as separator between logs zt_logger.info("\n\n" + str(e) + "\n\n") zt_logger.exception(e) sys.exit(1) except (display_common.AttrSpecError, display_common.ScreenError) as e: # NOTE: Strictly this is not necessarily just a theme error # FIXME: Add test for this - once loading takes place after UI setup print(in_color('red', "\nPossible theme error: {}.".format(e))) # Acts as separator between logs zt_logger.info("\n\n" + str(e) + "\n\n") zt_logger.exception(e) sys.exit(1) except Exception as e: zt_logger.info("\n\n" + str(e) + "\n\n") zt_logger.exception(e) if args.debug: sys.stdout.flush() traceback.print_exc(file=sys.stderr) run_debugger = input("Run Debugger? (y/n): ") if run_debugger in ["y", "Y", "yes"]: # Open PUDB Debuuger import pudb pudb.post_mortem() if hasattr(e, 'extra_info'): print( "\n" + in_color("red", e.extra_info), # type: ignore file=sys.stderr) print(in_color( "red", "\nZulip Terminal has crashed!" "\nPlease refer to " + TRACEBACK_LOG_FILENAME + " for full log of the error."), file=sys.stderr) print("You can ask for help at:", file=sys.stderr) print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() import tempfile with tempfile.NamedTemporaryFile(prefix="zulip_term_profile.", suffix=".dat", delete=False) as profile_file: profile_path = profile_file.name # Dump stats only after temporary file is closed (for Win NT+ case) prof.dump_stats(profile_path) print("Profile data saved to {0}.\n" "You can visualize it using e.g. `snakeviz {0}`".format( profile_path)) sys.exit(1)
def main(options: Optional[List[str]]=None) -> None: """ Launch Zulip Terminal. """ argv = options if options is not None else sys.argv[1:] args = parse_args(argv) set_encoding('utf-8') if args.profile: import cProfile prof = cProfile.Profile() prof.enable() if args.version: print('Zulip Terminal ' + ZT_VERSION) sys.exit(0) if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = '~/zuliprc' try: zterm = parse_zuliprc(zuliprc_path) if args.autohide: zterm['autohide'] = (args.autohide, 'on command line') if args.theme: theme_to_use = (args.theme, 'on command line') else: theme_to_use = zterm['theme'] available_themes = all_themes() if theme_to_use[0] not in available_themes: print("Invalid theme '{}' was specified {}." .format(*theme_to_use)) print("The following themes are available:") for theme in available_themes: print(" ", theme) print("Specify theme in zuliprc file or override " "using -t/--theme options on command line.") sys.exit(1) print("Loading with:") print(" theme '{}' specified {}.".format(*theme_to_use)) complete, incomplete = complete_and_incomplete_themes() if theme_to_use[0] in incomplete: print(in_color('yellow', " WARNING: Incomplete theme; " "results may vary!\n" " (you could try: {})". format(", ".join(complete)))) print(" autohide setting '{}' specified {}." .format(*zterm['autohide'])) # For binary settings # Specify setting in order True, False valid_settings = { 'autohide': ['autohide', 'no_autohide'], 'notify': ['enabled', 'disabled'], } boolean_settings = dict() # type: Dict[str, bool] for setting, valid_values in valid_settings.items(): if zterm[setting][0] not in valid_values: print("Invalid {} setting '{}' was specified {}." .format(setting, *zterm[setting])) print("The following options are available:") for option in valid_values: print(" ", option) print("Specify the {} option in zuliprc file.".format(setting)) sys.exit(1) boolean_settings[setting] = (zterm[setting][0] == valid_values[0]) color_depth = int(args.color_depth) if color_depth == 1: theme_data = theme_with_monochrome_added(THEMES[theme_to_use[0]]) else: theme_data = THEMES[theme_to_use[0]] Controller(zuliprc_path, theme_data, int(args.color_depth), **boolean_settings).main() except ServerConnectionFailure as e: print(in_color('red', "\nError connecting to Zulip server: {}.".format(e))) # Acts as separator between logs logging.info("\n\n" + str(e) + "\n\n") logging.exception(e) sys.exit(1) except (display_common.AttrSpecError, display_common.ScreenError) as e: # NOTE: Strictly this is not necessarily just a theme error # FIXME: Add test for this - once loading takes place after UI setup print(in_color('red', "\nPossible theme error: {}.".format(e))) # Acts as separator between logs logging.info("\n\n" + str(e) + "\n\n") logging.exception(e) sys.exit(1) except Exception as e: logging.info("\n\n" + str(e) + "\n\n") logging.exception(e) if args.debug: sys.stdout.flush() traceback.print_exc(file=sys.stderr) run_debugger = input("Run Debugger? (y/n): ") if run_debugger in ["y", "Y", "yes"]: # Open PUDB Debuuger import pudb pudb.post_mortem() if hasattr(e, 'extra_info'): print("\n" + in_color("red", e.extra_info), # type: ignore file=sys.stderr) print(in_color("red", "\nZulip Terminal has crashed!" "\nPlease refer to " + LOG_FILENAME + " for full log of" " the error."), file=sys.stderr) print("You can ask for help at:", file=sys.stderr) print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() prof.dump_stats("/tmp/profile.data") print("Profile data saved to /tmp/profile.data") print("You can visualize it using e.g." "`snakeviz /tmp/profile.data`") sys.exit(1)
def controller(self, mocker) -> None: self.config_file = 'path/to/zuliprc' self.theme = 'default' self.autohide = True # FIXME Add tests for no-autohide return Controller(self.config_file, self.theme, self.autohide)
def controller(self, mocker) -> None: self.config_file = 'path/to/zuliprc' self.theme = 'default' mocker.patch('zulipterminal.core.Controller.register') return Controller(self.config_file, self.theme)
def controller(self, mocker) -> None: self.config_file = 'path/to/zuliprc' self.theme = 'default' mocker.patch('zulipterminal.core.Controller.' 'register_initial_desired_events') return Controller(self.config_file, self.theme)
def main(options: Optional[List[str]] = None) -> None: """ Launch Zulip Terminal. """ argv = options if options is not None else sys.argv[1:] args = parse_args(argv) set_encoding("utf-8") if args.debug: print("NOTE: Debug mode enabled; API calls being logged to {}.".format( in_color("blue", API_CALL_LOG_FILENAME))) requests_logfile_handler = logging.FileHandler(API_CALL_LOG_FILENAME) requests_logger.addHandler(requests_logfile_handler) else: requests_logger.addHandler(logging.NullHandler()) if args.profile: import cProfile prof = cProfile.Profile() prof.enable() if args.version: print(f"Zulip Terminal {ZT_VERSION}") sys.exit(0) if args.list_themes: print(list_themes()) sys.exit(0) if args.config_file: zuliprc_path = args.config_file else: zuliprc_path = "~/zuliprc" try: zterm = parse_zuliprc(zuliprc_path) if args.autohide: zterm["autohide"] = (args.autohide, "on command line") if args.theme: theme_to_use = (args.theme, "on command line") else: theme_to_use = zterm["theme"] if (zterm["footlinks"][1] == ZULIPRC_CONFIG and zterm["maximum-footlinks"][1] == ZULIPRC_CONFIG): exit_with_error( "Footlinks property is not allowed alongside maximum-footlinks" ) if (zterm["maximum-footlinks"][1] == ZULIPRC_CONFIG and int(zterm["maximum-footlinks"][0]) < 0): exit_with_error("Minimum value allowed for maximum-footlinks is 0") if zterm["footlinks"][1] == ZULIPRC_CONFIG: if zterm["footlinks"][0] == DEFAULT_SETTINGS["footlinks"]: maximum_footlinks = 3 else: maximum_footlinks = 0 else: maximum_footlinks = int(zterm["maximum-footlinks"][0]) available_themes = all_themes() theme_aliases = aliased_themes() is_valid_theme = (theme_to_use[0] in available_themes or theme_to_use[0] in theme_aliases) if not is_valid_theme: exit_with_error( "Invalid theme '{}' was specified {}.".format(*theme_to_use), helper_text=list_themes(), ) if theme_to_use[0] not in available_themes: # theme must be an alias, as it is valid real_theme_name = theme_aliases[theme_to_use[0]] theme_to_use = ( real_theme_name, "{} (by alias '{}')".format(theme_to_use[1], theme_to_use[0]), ) if args.color_depth: zterm["color-depth"] = (args.color_depth, "on command line") color_depth_str = zterm["color-depth"][0] if color_depth_str == "24bit": color_depth = 2**24 else: color_depth = int(color_depth_str) if args.notify: zterm["notify"] = (args.notify, "on command line") print("Loading with:") print(" theme '{}' specified {}.".format(*theme_to_use)) complete, incomplete = complete_and_incomplete_themes() if theme_to_use[0] in incomplete: if complete: incomplete_theme_warning = ( " WARNING: Incomplete theme; results may vary!\n" " (you could try: {})".format(", ".join(complete))) else: incomplete_theme_warning = ( " WARNING: Incomplete theme; results may vary!\n" " (all themes are incomplete)") print(in_color("yellow", incomplete_theme_warning)) print(" autohide setting '{}' specified {}.".format( *zterm["autohide"])) if zterm["footlinks"][1] == ZULIPRC_CONFIG: print( " maximum footlinks value '{}' specified {} from footlinks.". format(maximum_footlinks, zterm["footlinks"][1])) else: print(" maximum footlinks value '{}' specified {}.".format( *zterm["maximum-footlinks"])) print(" color depth setting '{}' specified {}.".format( *zterm["color-depth"])) print(" notify setting '{}' specified {}.".format(*zterm["notify"])) # For binary settings # Specify setting in order True, False valid_settings = { "autohide": ["autohide", "no_autohide"], "notify": ["enabled", "disabled"], "color-depth": ["1", "16", "256", "24bit"], } boolean_settings: Dict[str, bool] = dict() for setting, valid_values in valid_settings.items(): if zterm[setting][0] not in valid_values: helper_text = ( ["Valid values are:"] + [f" {option}" for option in valid_values] + [f"Specify the {setting} option in zuliprc file."]) exit_with_error( "Invalid {} setting '{}' was specified {}.".format( setting, *zterm[setting]), helper_text="\n".join(helper_text), ) if setting == "color-depth": break boolean_settings[setting] = zterm[setting][0] == valid_values[0] theme_data = generate_theme(theme_to_use[0], color_depth) Controller( zuliprc_path, maximum_footlinks, theme_to_use[0], theme_data, color_depth, args.explore, **boolean_settings, ).main() except ServerConnectionFailure as e: # Acts as separator between logs zt_logger.info(f"\n\n{e}\n\n") zt_logger.exception(e) exit_with_error(f"\nError connecting to Zulip server: {e}.") except (display_common.AttrSpecError, display_common.ScreenError) as e: # NOTE: Strictly this is not necessarily just a theme error # FIXME: Add test for this - once loading takes place after UI setup # Acts as separator between logs zt_logger.info(f"\n\n{e}\n\n") zt_logger.exception(e) exit_with_error(f"\nPossible theme error: {e}.") except Exception as e: zt_logger.info("\n\n{e}\n\n") zt_logger.exception(e) if args.debug: sys.stdout.flush() traceback.print_exc(file=sys.stderr) run_debugger = input("Run Debugger? (y/n): ") if run_debugger in ["y", "Y", "yes"]: # Open PUDB Debugger import pudb pudb.post_mortem() if hasattr(e, "extra_info"): print(in_color("red", f"\n{e.extra_info}"), file=sys.stderr) # type: ignore print( in_color( "red", "\nZulip Terminal has crashed!" f"\nPlease refer to {TRACEBACK_LOG_FILENAME}" " for full log of the error.", ), file=sys.stderr, ) print( "You can ask for help at:" "\nhttps://chat.zulip.org/#narrow/stream/206-zulip-terminal", file=sys.stderr, ) print("\nThanks for using the Zulip-Terminal interface.\n") sys.stderr.flush() finally: if args.profile: prof.disable() import tempfile with tempfile.NamedTemporaryFile(prefix="zulip_term_profile.", suffix=".dat", delete=False) as profile_file: profile_path = profile_file.name # Dump stats only after temporary file is closed (for Win NT+ case) prof.dump_stats(profile_path) print("Profile data saved to {0}.\n" "You can visualize it using e.g. `snakeviz {0}`".format( profile_path)) sys.exit(1)