def _loader_thread(self, logpath, session_name, session_notes): Clock.schedule_once(lambda dt: self.dispatch('on_import_start')) success = True message = '' session_id = None try: session_id = self.datastore.import_datalog(logpath, session_name, session_notes, self._update_progress) except Exception as e: success = False message = str(e) ExceptionManager.handle_exception(e) Clock.schedule_once(lambda dt: self.dispatch('on_import_complete', session_id, success, message))
def _loader_thread(self, logpath, session_name, session_notes): Clock.schedule_once(lambda dt: self.dispatch('on_import_start')) success = True message = '' session_id = None try: session_id = self.datastore.import_datalog(logpath, session_name, session_notes, self._update_progress) except Exception as e: success = False message = str(e) ExceptionManager.handle_exception(e) Clock.schedule_once(lambda dt: self.dispatch( 'on_import_complete', session_id, success, message))
def run_app(): class CrashHandler(ExceptionHandler): def handle_exception(self, inst): ex_type, ex, tb = sys.exc_info() trace = "".join(traceback.format_tb(tb)) app = MDApp.get_running_app() if app and app.gui: app.gui.log( f"Exception {inst.__class__}: {inst.args}\n{trace}", OUTPUT_ERROR) else: print(f"Exception {inst.__class__}: {inst.args}\n{trace}") return ExceptionManager.PASS ExceptionManager.add_handler(CrashHandler()) app = KaTrainApp() signal.signal(signal.SIGINT, app.signal_handler) app.run()
def mainloop(self): while not EventLoop.quit and EventLoop.status == 'started': try: self._mainloop() except BaseException as inst: # use exception manager first r = ExceptionManager.handle_exception(inst) if r == ExceptionManager.RAISE: stopTouchApp() raise else: pass
async def run_app_async(cls_or_app, async_lib=None): """Entrance method used to start the App. It runs, or instantiates and runs a :class:`MoreKivyApp` type instance. """ from kivy.core.window import Window handler = _MoreKivyAppHandler() ExceptionManager.add_handler(handler) app = cls_or_app() if inspect.isclass(cls_or_app) else cls_or_app Window.fbind('on_request_close', app.ask_cannot_close) try: await app.async_run(async_lib=async_lib) except Exception as e: app.handle_exception(e, exc_info=sys.exc_info()) try: app.clean_up() except Exception as e: app.handle_exception(e, exc_info=sys.exc_info()) Window.funbind('on_request_close', app.ask_cannot_close) ExceptionManager.remove_handler(handler)
def mainloop(self): while not EventLoop.quit and EventLoop.status == 'started': try: self._mainloop() if not pygame.display.get_active(): pygame.time.wait(100) except BaseException as inst: # use exception manager first r = ExceptionManager.handle_exception(inst) if r == ExceptionManager.RAISE: stopTouchApp() raise else: pass
def mainloop(self): while not EventLoop.quit and EventLoop.status == 'started': try: self._mainloop() if not pygame.display.get_active(): pygame.time.wait(100) except BaseException, inst: # use exception manager first r = ExceptionManager.handle_exception(inst) if r == ExceptionManager.RAISE: stopTouchApp() raise else: pass
async def async_mainloop(self): from kivy.base import ExceptionManager, stopTouchApp while not self.quit and self.status == 'started': try: await self.async_idle() if self.window: self.window.mainloop() except BaseException as inst: # use exception manager first r = ExceptionManager.handle_exception(inst) if r == ExceptionManager.RAISE: stopTouchApp() raise else: pass
def mainloop(self): # don't known why, but pygame required a resize event # for opengl, before mainloop... window reinit ? #self.dispatch('on_resize', *self.size) while not EventLoop.quit and EventLoop.status == 'started': try: self._mainloop() except BaseException as inst: # use exception manager first r = ExceptionManager.handle_exception(inst) if r == ExceptionManager.RAISE: stopTouchApp() raise else: pass
if is_recording else 'Session recording stopped', length_long=True) if __name__ == '__main__': class CrashHandler(ExceptionHandler): def handle_exception(self, exception_info): if type(exception_info) == KeyboardInterrupt: Logger.info("CrashHander: KeyboardInterrupt") App.get_running_app().stop() Logger.critical("CrashHandler: Caught exception in Kivy loop: " + str(exception_info)) Logger.critical(traceback.format_exc()) if 'sentry_client' in globals(): ident = sentry_client.captureException(value=exception_info) Logger.critical("CrashHandler: crash caught: Reference is %s" % ident) return ExceptionManager.PASS ExceptionManager.add_handler(CrashHandler()) try: RaceCaptureApp().run() except: if 'sentry_client' in globals(): ident = sentry_client.captureException() Logger.error("Main: crash caught: Reference is %s" % ident) traceback.print_exc() else: raise
def __init__(self, add_handler=True): if add_handler: ExceptionManager.add_handler(self)
self.cam_lens_closer2.widget = widget = FormulaWidget( formula=self.cam_lens_closer2, description='((4/4) Fourth lens in the sequence.', name='L4') widget.populate_widget() container.add_widget(widget) from kivy.core.window import Window inspector.create_inspector(Window, root) return root if __name__ == '__main__': class _AppHandler(ExceptionHandler): def handle_exception(self, inst): Logger.error(inst, exc_info=sys.exc_info()) return ExceptionManager.PASS handler = _AppHandler() ExceptionManager.add_handler(handler) app = OpticsApp() try: app.run() except Exception as e: Logger.error(e, exc_info=sys.exc_info()) ExceptionManager.remove_handler(handler)
def start(): """This is the main function that is called unconditionally. Unconditionally means, regardless of whether __name__ == '__main__' or not. It is all a mess but with historical reasons where imports had to be in the right order :). It would be nice to refactor it one day. """ # Enforce all requirements so that the program doesn't crash in the middle of execution. if __name__ == '__main__': from utils.requirements import check_libraries_requirements check_libraries_requirements() # Import multiprocessing and enable freeze_support which is needed on windows import multiprocessing multiprocessing.freeze_support() # Import kivy as soon as possible to let it eat all the kivy args from sys.argv import kivy # # we have to protect the instantiation of the kivy app, cause # of the use of multiprocessing. If you spawn a new thread or process # it loads this file again. So there is the need of the __main__ guard. # if __name__ == "__main__": import sys # initialize settings class from utils.settings import Settings settings = Settings(sys.argv[1:]) import launcher_config # HACK: clear sys.argv for kivy. Keep only the first element # sys.argv = sys.argv[0:1] # configure kivy from kivy import resources from kivy.config import Config from utils.paths import ( get_common_resources_path, get_resources_path, get_source_path, ) from utils.devmode import devmode default_log_level = devmode.get_log_level('info') resources.resource_add_path(get_common_resources_path()) resources.resource_add_path(get_source_path()) resources.resource_add_path(get_resources_path()) Config.set('kivy', 'window_icon', get_resources_path(launcher_config.icon)) Config.set('kivy', 'log_level', default_log_level) Config.set('input', 'mouse', 'mouse,disable_multitouch') if not settings.get('update'): Config.set('graphics', 'resizable', 0) Config.set('graphics', 'width', 1000) Config.set('graphics', 'height', 666) Config.set('graphics', 'borderless', 0) else: Config.set('graphics', 'resizable', 0) Config.set('graphics', 'width', 400) Config.set('graphics', 'height', 150) Config.set('graphics', 'borderless', 1) # # other imports # from kivy.app import App from kivy.uix.label import Label from kivy.uix.widget import Widget from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.rst import RstDocument from kivy.uix.stacklayout import StackLayout from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelItem, TabbedPanelStrip, TabbedPanelHeader from kivy.graphics import Line, Color from kivy.properties import NumericProperty, ObjectProperty, BooleanProperty, StringProperty from kivy.core.window import Window from kivy.clock import Clock from kivy.logger import Logger from kivy.uix.screenmanager import ScreenManager, Screen from kivy.core.text import LabelBase from kivy.base import ExceptionManager from utils.app import BaseApp from view.numberinput import NumberInput from view.dynamicbutton import DynamicButton from view.hoverbutton import HoverButton from view.statusimage import StatusImage from view.errorpopup import error_popup_decorator from view.errorpopup import PopupHandler from view.modlist import ModList from view.serverlist import ServerListScrolled from view.simplewidgets import CheckLabel from gui.mainwidget import MainWidget from gui.updatermainwidget import UpdaterMainWidget from gui.installscreen import InstallScreen from gui.prefscreen import PrefScreen import logging Logger.info('Para: Starting MAIN PROCESS') if settings.get('use_exception_popup') == True: ExceptionManager.add_handler(PopupHandler()) class MainScreenManager(ScreenManager): pass class LauncherApp(BaseApp): """Main class for the normal app""" title = launcher_config.launcher_name.encode('utf-8') def __init__(self, settings): super(LauncherApp, self).__init__() self.settings = settings def build(self): logger = logging.getLogger('concurrent.futures') logger.addHandler(logging.StreamHandler()) return MainWidget() class SelfUpdaterApp(BaseApp): """app which starts the self updater""" title = '{} updater'.format(launcher_config.launcher_name).encode('utf-8') def __init__(self, settings): super(SelfUpdaterApp, self).__init__() self.settings = settings def build(self): logger = logging.getLogger('concurrent.futures') logger.addHandler(logging.StreamHandler()) return UpdaterMainWidget() if __name__ == '__main__': launcher_app = None if settings.get('update'): print 'launching self updater' launcher_app = SelfUpdaterApp(settings).run() else: launcher_app = LauncherApp(settings) launcher_app.run = error_popup_decorator(launcher_app.run) launcher_app.run()
# os.environ['KIVY_METRICS_DENSITY'] = '1' # os.environ['KIVY_METRICS_FONTSCALE'] = '1.2' # Debug OpenGL # os.environ['KIVY_GL_DEBUG'] = '1' import kivy # Apply settings of this app from utils import app_config # Add exception handler if IS_BINARY: from kivy.base import ExceptionManager from kivyrtc.tools.bug_reporter import BugHandler ExceptionManager.add_handler(BugHandler()) kivy.require('1.11.0') from kivy.logger import Logger from kivyrtc.app import KivyRTCApp app = KivyRTCApp(__app_name__, DATA_DIR) if not IS_RELEASE: for name in logging.root.manager.loggerDict: if name == 'kivy': continue logging.getLogger(name).setLevel(logging.DEBUG) # Print important info of app
if value == "1": # Boolean settings values are 1/0, not True/False if self.rc_config.connectivityConfig.cellConfig.cellEnabled: alertPopup('Telemetry error', "Turn off RaceCapture's telemetry module for app to stream telemetry.") self._telemetry_connection.telemetry_enabled = True else: self._telemetry_connection.telemetry_enabled = False class CrashHandler(ExceptionHandler): def handle_exception(self, exception_info): if type(exception_info) == KeyboardInterrupt: Logger.info("CrashHander: KeyboardInterrupt") sys.exit() Logger.critical("CrashHandler: Caught exception in Kivy loop: " + str(exception_info)) Logger.critical(traceback.format_exc()) if 'sentry_client' in globals(): ident = sentry_client.captureException(value=exception_info) Logger.critical("CrashHandler: crash caught: Reference is %s" % ident) return ExceptionManager.PASS if __name__ == '__main__': ExceptionManager.add_handler(CrashHandler()) try: RaceCaptureApp().run() except: if 'sentry_client' in globals(): ident = sentry_client.captureException() Logger.error("Main: crash caught: Reference is %s" % ident) traceback.print_exc() else: raise
def install_exception_handler(): ExceptionManager.add_handler(ErrorMessageOnException())
def install_exception_handler(): """Install `ErrorMessageOnException` exception handler.""" ExceptionManager.add_handler(ErrorMessageOnException())
def handle_exception(self, e): from kivy.base import ExceptionManager if ExceptionManager.handle_exception(e) == ExceptionManager.RAISE: raise
class MainApp(MDApp): """ """ # TODO: In Pycharm Click Menu Code > Inspect Code... and fix (weak)warnings # TODO: maybe foresee a transposing option at song level, while preprocessing? # Foresee custom handling of errors, user can bypass them (maybe own mistake) or quit the app, but he sees pop up of the error: ExceptionManager.add_handler(TFExceptionHandler()) def __init__(self, **kwargs): self.theme_cls.theme_style = "Light" self.theme_cls.primary_palette = "Brown" self.theme_cls.accent_palette = "LightGreen" super().__init__(**kwargs) self._main_widget = None self._exception_counter = 0 self.ddm = None self._context_menus = None # To prevent the window from closing, when 'X' is pressed on the windows itself: Window.bind(on_request_close=self.on_stop) Window.exit_on_escape = 1 # TODO: Test how fullscreen must be used decently: fullscreen option has been deprecated, use Window.borderless or the borderless Config option instead #Window.fullscreen = 'fake' # False, True, 'auto', 'fake' are the possibilities: https://kivy.org/doc/stable/api-kivy.config.html#module-kivy.config he ‘fake’ option has been deprecated, use the borderless property instead. # Window.maximize() # Linux way to kill fullscreen app when it doesn't want to close: # Ctrl+Alt+F1 > tty1 client (login, remember that numeric extension of keyboard does not work here) next try to # {ps aux | less} or {top}, then you will see the list of processes currently active, find the python process # {kill -9 27890} (this command sends SIGKILL next return to cinnamon GUI with {Ctrl+Alt+F7} # Create ToneFlow-settings object and corresponding settings: kv_file_main_widget = str(curr_file.parents[1] / "view" / (curr_file.with_suffix(".kv")).name) TFSettings(kv_file_main_widget) def build(self): self.icon = str( pl.Path(CU.tfs.dic['IMG_DIR_PATH'].value) / "ToneFlow_Logo_TaskBarIcon.png") self._main_widget.ids.scr_mngr.add_widget(CU.tfs) # Initialize the context_menus as an empty list: self.create_context_menus([]) return self._main_widget def create_uninstantiated_screen(self, screen_class): class_name = screen_class.__name__ # Builder.load_file(str(curr_file.parents[1] / "view" / (pl.Path(class_name).with_suffix(".kv")).name)) screen_object = screen_class() return screen_object def get_main_widget(self): return self._main_widget def set_main_widget(self, main_widget): self._main_widget = main_widget def get_context_menus(self): return self._context_menus def set_context_menus(self, context_menus): self._context_menus = context_menus self.create_context_menus(context_menus) main_widget = property(get_main_widget, set_main_widget) context_menus = property(get_context_menus, set_context_menus) def create_context_menus(self, menu_items): """ Goal of context menus: Depending on the screen other context oriented options should appear under the three vertical dots :param menu_items: A dictionary with the name of the context_menu mapped to its callback :return: """ # You can include an icon as well in the context menu's, clicks on it however do not trigger the intended callback: dropdown_menu_items = [{ "icon": "checkbox-blank-circle", "divider": None, "text": f"{key}" } for key in menu_items] if (menu_items is not None): self._context_menus = menu_items self.ddm = TFDropdownMenu( caller=self.main_widget.ids.toolbar.ids.right_actions, use_icon_item=False, items=dropdown_menu_items, width_mult=4, callback=lambda *args, **kwargs: (menu_items[args[0].text](args, kwargs), self.ddm.dismiss())) else: self._context_menus = [] self.ddm = TFDropdownMenu( caller=self.main_widget.ids.toolbar.ids.right_actions, use_icon_item=False, items=[], width_mult=4, callback=lambda *args, **kwargs: self.ddm.dismiss()) def on_pause(self): return True def on_start(self): # As a proposal, the actual (default)value of the tf_workspace_path-param is copied to the clipboard: workspace_path_proposal = CU.tfs.dic['tf_workspace_path'].default_value pyperclip.copy(str(workspace_path_proposal)) # In case the user did configure a customized path, that path will be filled in: text = "" if (CU.tfs.dic['tf_workspace_path'].default_value == CU.tfs.dic['tf_workspace_path'].value ) else f"{CU.tfs.dic['tf_workspace_path'].value}" content_obj = BoxLayout(orientation='vertical', spacing="12dp", size_hint_y=None) # mdlbl1 = MDLabel(text=str(CU.tfs.dic['EXPLANATION_WORKSPACE_PATH'].value)) mdtf1 = MDTextField() mdtf1.text = text mdtf1.hint_text = f"{CU.tfs.dic['tf_workspace_path'].description}" mdtf1.helper_text = str(CU.tfs.dic['EXPLANATION_WORKSPACE_PATH'].value) mdtf1.helper_text_mode = "on_focus" # content_obj.add_widget(mdlbl1) content_obj.add_widget(mdtf1) CU.show_input_dialog( title= f"Enter Path to \"{CU.tfs.dic['WORKSPACE_NAME'].value}\"-Folder or to its Parent Folder", content_obj=content_obj, # hint_text=f"{CU.tfs.dic['tf_workspace_path'].description}", # size_hint=(.8, .4), text_button_ok="Load/Create", text_button_cancel="Cancel", ok_callback_set=lambda *args, **kwargs: (CU.tfs.dic['tf_workspace_path'].set_value(mdtf1.text), toast(str(CU.tfs.dic['tf_workspace_path'].value))), cancel_callback_set=lambda *args, **kwargs: toast( f"{CU.tfs.dic['WORKSPACE_NAME'].value} can still be changed anytime from the settings" )) def on_stop(self, *args, **kwargs): # Important: *args and **kwargs can both be passed to a method, *args takes care of all unexpected # (variable amount) of positional arguments and **kwargs takes care of all unexpected (variable amount) # of named arguments. CU.show_ok_cancel_dialog( title="Confirmation dialog", text= f"Are you sure you want to [color={get_hex_from_color(self.theme_cls.primary_color)}][b]quit[/b][/color] {CU.tfs.dic['APP_NAME'].value}?", size_hint=(0.5, 0.3), text_button_ok="Yes", text_button_cancel="No", ok_callback_set=lambda *args, **kwargs: self.stop(), cancel_callback_set=lambda *args, **kwargs: toast("Not quitting")) return True # def open_context_menu(self, instance): # if (self.context_menus != None): # mddm = MDDropdownMenu(caller=self._main_widget.ids., items=self.context_menus, width_mult=3).open(instance) def open_settings(self, *args): # TODO: Experiment in later stage with kivy settings, because it might ruin the setup return False def set_theme_toolbar(self, primary_color, accent_color): if (primary_color is not None and accent_color is not None): primary_color, accent_color = str(primary_color), str(accent_color) if (primary_color in palette) and (accent_color in palette): # Update the primary and accent colors self.theme_cls.primary_palette = primary_color self.theme_cls.accent_palette = accent_color def set_title_toolbar(self, title): """Set string title in MDToolbar for the whole application.""" self._main_widget.ids.toolbar.title = title def show_screen(self, screen_property): # Get a shorter alias for the screen_manager object: scr_mngr = self._main_widget.ids.scr_mngr # Extract class & class_name: screen_class = screen_property.value class_name = screen_class.__name__ # Update the title, theme: self.set_title_toolbar(screen_property.name) self.set_theme_toolbar(screen_class.theme_primary_color, screen_class.theme_accent_color) # If the scr_mngr doesn't have such screen yet, make one: if (not scr_mngr.has_screen(class_name)): scr_mngr.add_widget( self.create_uninstantiated_screen(screen_class)) # Update the context menu's and finally show toast when ready: self.create_context_menus( scr_mngr.get_screen(class_name).context_menus) scr_mngr.current = class_name toast(class_name)
def init_exception_handling(): ExceptionManager.add_handler(PopUpHandler())
self.cam_lens_closer2.widget = widget = FormulaWidget( formula=self.cam_lens_closer2, description='((4/4) Fourth lens in the sequence.', name='L4') widget.populate_widget() container.add_widget(widget) from kivy.core.window import Window inspector.create_inspector(Window, root) return root if __name__ == '__main__': class _CPLComHandler(ExceptionHandler): def handle_exception(self, inst): Logger.error(inst, exc_info=sys.exc_info()) return ExceptionManager.PASS handler = _CPLComHandler() ExceptionManager.add_handler(handler) app = OpticsApp() try: app.run() except Exception as e: Logger.error(e, exc_info=sys.exc_info()) ExceptionManager.remove_handler(handler)
def build(self): self.title = 'Scribe3 | {}'.format(scribe_globals.BUILD_NUMBER) self.setup_files() ExceptionManager.add_handler(RuntimeErrorHandler(self)) return BoxLayout()
type="custom", content_cls=self.license) self.infodialog = MDDialog(title="More Info:", type="custom", content_cls=self.moreinfo) self.yeardialog = MDDialog(title=f"Choose Year:", type="custom", content_cls=recycle) self.yeardialog.size_hint_x = .9 self.licensedialog.size_hint_x = .9 self.infodialog.size_hint_x = .9 def callback(self, instance): self.root.ids.sm.transition.direction = 'left' self.root.ids.sm.current = 'chooser' class E(ExceptionHandler): def handle_exception(self, inst): Logger.exception('Exception caught by ExceptionHandler') return ExceptionManager.PASS ExceptionManager.add_handler(E()) if __name__ == '__main__': main().run()
if waiting_process: reactor.cb(reactor.mp_complete, (callback.__name__, waketime, "kgui"), res, process=waiting_process) def kivy_callback(*args, **kwargs): Clock.schedule_del_safe(lambda: run_callback(*args, **kwargs)) # Catch KGUI exceptions and display popups class PopupExceptionHandler(ExceptionHandler): def handle_exception(self, exception): if not TESTING: tr = ''.join(traceback.format_tb(exception.__traceback__)) App.get_running_app().handle_critical_error(tr + "\n\n" + repr(exception)) logging.exception("UI-Exception, popup invoked") return ExceptionManager.PASS ExceptionManager.add_handler(PopupExceptionHandler()) # Load kv-files: # Add parent directory to sys.path so kv-files (kivy/../parser.py) can import from it site.addsitedir(p.kgui_dir) # load a custom style.kv with changes to popup and more Builder.unload_file(join(kivy_data_dir, "style.kv")) # All files to read (order is important), main.kv is read first, automatically for fname in ("style.kv", "overwrites.kv", "elements.kv", "home.kv", "timeline.kv", "files.kv", "settings.kv"): Builder.load_file(join(p.kgui_dir, "kv", fname)) # Entry point, order of execution: __init__() run() main.kv on_start() handle_connect() handle_ready() def load_config(config): kgui_object = mainApp(config) logging.info("Kivy app.run")
import watchdog # NOQA class ExceptionClass(ExceptionHandler): def handle_exception(self, inst): if isinstance(inst, (KeyboardInterrupt, SystemExit)): return ExceptionManager.RAISE app = MDApp.get_running_app() if not app.DEBUG and not app.RAISE_ERROR: return ExceptionManager.RAISE app.set_error(inst, tb=traceback.format_exc()) return ExceptionManager.PASS ExceptionManager.add_handler(ExceptionClass()) class MDApp(BaseApp): """HotReload Application class.""" DEBUG = BooleanProperty("DEBUG" in os.environ) """ Control either we activate debugging in the app or not. Defaults depend if 'DEBUG' exists in os.environ. :attr:`DEBUG` is a :class:`~kivy.properties.BooleanProperty`. """ FOREGROUND_LOCK = BooleanProperty(False) """