Skip to content
Snippets Groups Projects
Select Git revision
  • b4cbca182d66b62c2dadb8328127a2b5569c53d3
  • master default protected
  • network/gtest-1000 protected
  • upgradable-multisig
  • runtime/gtest-1000
  • network/gdev-800 protected
  • cgeek/issue-297-cpu
  • gdev-800-tests
  • update-docker-compose-rpc-squid-names
  • fix-252
  • 1000i100-test
  • hugo/tmp-0.9.1
  • network/gdev-803 protected
  • hugo/endpoint-gossip
  • network/gdev-802 protected
  • hugo/distance-precompute
  • network/gdev-900 protected
  • tuxmain/anonymous-tx
  • debug/podman
  • hugo/195-doc
  • hugo/195-graphql-schema
  • gtest-1000-0.11.0 protected
  • gtest-1000 protected
  • gdev-900-0.10.1 protected
  • gdev-900-0.10.0 protected
  • gdev-900-0.9.2 protected
  • gdev-800-0.8.0 protected
  • gdev-900-0.9.1 protected
  • gdev-900-0.9.0 protected
  • gdev-803 protected
  • gdev-802 protected
  • runtime-801 protected
  • gdev-800 protected
  • runtime-800-bis protected
  • runtime-800 protected
  • runtime-800-backup protected
  • runtime-701 protected
  • runtime-700 protected
  • runtime-600 protected
  • runtime-500 protected
  • v0.4.1 protected
41 results

git-conventions.md

Blame
    • Hugo Trentesaux's avatar
      ef73a0d0
      improve documentation (!101) · ef73a0d0
      Hugo Trentesaux authored and Éloïs's avatar Éloïs committed
      * fix
      
      * doc(end2end): detail test users
      
      * doc(all): update docker tag
      
      update docker image name from 0.2.0 to 0.3.0
      use "docker compose" everywhere instead of "docker-compose"
      improve table of content
      fix layout
      
      * doc(all): improve docs
      
      add logo to readme
      add table of content
      rewording
      complete
      
      * doc(all): fix typos
      ef73a0d0
      History
      improve documentation (!101)
      Hugo Trentesaux authored and Éloïs's avatar Éloïs committed
      * fix
      
      * doc(end2end): detail test users
      
      * doc(all): update docker tag
      
      update docker image name from 0.2.0 to 0.3.0
      use "docker compose" everywhere instead of "docker-compose"
      improve table of content
      fix layout
      
      * doc(all): improve docs
      
      add logo to readme
      add table of content
      rewording
      complete
      
      * doc(all): fix typos
    main.py 6.69 KiB
    import locale
    import asyncio
    import logging
    import signal
    import sys
    import traceback
    
    from PyQt5.QtCore import Qt, QObject, QCoreApplication
    from PyQt5.QtWidgets import QApplication, QMessageBox, QDialog, QPushButton, QLabel
    
    from duniterpy.api.errors import DuniterError
    
    from sakia.constants import GITLAB_NEW_ISSUE_PAGE_URL
    from sakia.helpers import single_instance_lock, cleanup_lock
    from quamash import QSelectorEventLoop
    from sakia.errors import NoPeerAvailable
    from sakia.app import Application
    from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController
    from sakia.gui.main_window.controller import MainWindowController
    from sakia.gui.preferences import PreferencesDialog
    from sakia.gui.widgets import QAsyncMessageBox
    from sakia.gui.dialogs.startup_uic import Ui_StartupDialog
    from sakia import __version__
    
    
    class StartupDialog(QDialog, Ui_StartupDialog):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            self.setWindowTitle("Sakia {version}".format(version=__version__))
    
        def closeEvent(self, event):
            """
            Overide close event to exit application if dialog is closed
    
            :param QDialogEvent event:
            :return:
            """
            cancel_connection()
    
    
    def exit_exception_handler(loop, context):
        """
        An exception handler which prints only on debug (used when exiting)
        :param loop: the asyncio loop
        :param context: the exception context
        """
    
        logging.debug("Exception handler executing")
        message = context.get("message")
        if not message:
            message = "Unhandled exception in event loop"
    
        try:
            exception = context["exception"]
        except KeyError:
            exc_info = False
        else:
            exc_info = (type(exception), exception, exception.__traceback__)
    
        logging.debug(
            "An unhandled exception occurred: {0}".format(message), exc_info=exc_info
        )
    
    
    def async_exception_handler(loop, context):
        """
        An exception handler which exits the program if the exception
        was not catch
        :param loop: the asyncio loop
        :param context: the exception context
        """
        logging.debug("Exception handler executing")
        message = context.get("message")
        if not message:
            message = "Unhandled exception in event loop"
    
        try:
            exception = context["exception"]
        except KeyError:
            exc_info = False
        else:
            exc_info = (type(exception), exception, exception.__traceback__)
    
        log_lines = [message]
        for key in [k for k in sorted(context) if k not in {"message", "exception"}]:
            log_lines.append("{}: {!r}".format(key, context[key]))
    
        logging.error("\n".join(log_lines), exc_info=exc_info)
        for line in log_lines:
            for ignored in (
                "feed_appdata",
                "do_handshake",
                "Unclosed",
                "socket.gaierror",
                "[Errno 110]",
            ):
                if ignored in line:
                    return
    
        if exc_info:
            for line in traceback.format_exception(*exc_info):
                for ignored in (
                    "feed_appdata",
                    "do_handshake",
                    "Unclosed",
                    "socket.gaierror",
                    "[Errno 110]",
                ):
                    if ignored in line:
                        return
        exception_message(log_lines, exc_info)
    
    
    def exception_handler(*exc_info):
        logging.error("An unhandled exception occured", exc_info=exc_info)
        exception_message(["An unhandled exception occured"], exc_info)
    
    
    def exception_message(log_lines, exc_info):
        stacktrace = traceback.format_exception(*exc_info) if exc_info else ""
        message = """
        {log_lines}
    
        ----
        {stacktrace}
        """.format(
            log_lines="\n".join(log_lines), stacktrace="\n".join(stacktrace)
        )
        mb = QMessageBox(
            QMessageBox.Critical,
            "Critical error",
            """A critical error occured. Select the details to display it.
                      Please report it to <a href='{}'>the developers Gitlab</a>""".format(
                GITLAB_NEW_ISSUE_PAGE_URL
            ),
            QMessageBox.Ok,
            QApplication.activeWindow(),
        )
        mb.setDetailedText(message)
        mb.setTextFormat(Qt.RichText)
    
        mb.exec()
    
    
    def cancel_connection(button=None):
        """
        Exit application
    
        :param QMessageBox button: Clicked button or None if close event
        :return:
        """
        print("Cancel connection! Exited.")
        sys.exit(0)
    
    
    def main():
        #  activate ctrl-c interrupt
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        sakia = QApplication(sys.argv)
    
        sys.excepthook = exception_handler
    
        # sakia.setStyle('Fusion')
        loop = QSelectorEventLoop(sakia)
        loop.set_exception_handler(async_exception_handler)
        # loop.set_debug(True)
        asyncio.set_event_loop(loop)
        # Fix quamash https://github.com/harvimt/quamash/issues/123
        asyncio.events._set_running_loop(loop)
    
        with loop:
            app = Application.startup(sys.argv, sakia, loop)
    
            lock = single_instance_lock(app.currency)
            if not lock:
                lock = single_instance_lock(app.currency)
                if not lock:
                    QMessageBox.critical(None, "Sakia", "Sakia is already running.")
    
                    sys.exit(1)
            app.start_coroutines()
            app.get_last_version()
            keep_trying = True
            while not app.blockchain_service.initialized():
                try:
                    box = StartupDialog()
                    box.show()
                    box.cancelButton.clicked.connect(cancel_connection)
                    loop.run_until_complete(app.initialize_blockchain())
                    box.hide()
                except (DuniterError, NoPeerAvailable) as e:
                    reply = QMessageBox.critical(
                        None,
                        "Error",
                        "Error connecting to the network: {:}. Keep Trying?".format(str(e)),
                        QMessageBox.Ok | QMessageBox.Abort,
                    )
                    if reply == QMessageBox.Ok:
                        loop.run_until_complete(PreferencesDialog(app).async_exec())
                    else:
                        break
            else:
                if not app.connection_exists():
                    conn_controller = ConnectionConfigController.create_connection(
                        None, app
                    )
                    loop.run_until_complete(conn_controller.async_exec())
                window = MainWindowController.startup(app)
                loop.run_forever()
            try:
                loop.set_exception_handler(exit_exception_handler)
                loop.run_until_complete(app.stop_current_profile())
                logging.debug("Application stopped")
            except asyncio.CancelledError:
                logging.info("CancelledError")
        logging.debug("Exiting")
        cleanup_lock(lock)
        sys.exit()
    
    
    if __name__ == "__main__":
        main()