Exemplo n.º 1
0
    def start(self, daemon=False):
        _fixWinsock()

        shared.daemon = daemon

        # is the application already running?  If yes then exit.
        shared.thisapp = singleinstance("", daemon)

        if daemon:
            with shared.printLock:
                print('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        knownnodes.loadKnownNodes()
        # Start the address generation thread
        addressGeneratorThread = addressGenerator()
        addressGeneratorThread.daemon = True  # close the main program even if there are threads left
        addressGeneratorThread.start()

        # Start the thread that calculates POWs
        singleWorkerThread = singleWorker()
        singleWorkerThread.daemon = True  # close the main program even if there are threads left
        singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        sqlLookup.daemon = False  # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
        sqlLookup.start()

        # Start the thread that calculates POWs
        objectProcessorThread = objectProcessor()
        objectProcessorThread.daemon = False  # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
        objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        singleCleanerThread.daemon = True  # close the main program even if there are threads left
        singleCleanerThread.start()

        shared.reloadMyAddressHashes()
        shared.reloadBroadcastSendersForWhichImWatching()

        if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
            try:
                apiNotifyPath = BMConfigParser().get(
                    'bitmessagesettings', 'apinotifypath')
            except:
                apiNotifyPath = ''
            if apiNotifyPath != '':
                with shared.printLock:
                    print('Trying to call', apiNotifyPath)

                call([apiNotifyPath, "startingUp"])
            singleAPIThread = singleAPI()
            singleAPIThread.daemon = True  # close the main program even if there are threads left
            singleAPIThread.start()

        connectToStream(1)

        singleListenerThread = singleListener()
        singleListenerThread.daemon = True  # close the main program even if there are threads left
        singleListenerThread.start()
        
        if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'):
            import upnp
            upnpThread = upnp.uPnPThread()
            upnpThread.start()

        if daemon == False and BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon') == False:
            if not depends.check_pyqt():
                print('PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download   or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
                sys.exit()

            import bitmessageqt
            bitmessageqt.run()
        else:
            BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
Exemplo n.º 2
0
    def start(self):
        """Start main application"""
        # pylint: disable=too-many-statements,too-many-branches,too-many-locals
        _fixSocket()
        adjustHalfOpenConnectionsLimit()

        config = BMConfigParser()
        daemon = config.safeGetBoolean('bitmessagesettings', 'daemon')

        try:
            opts, _ = getopt.getopt(
                sys.argv[1:], "hcdt",
                ["help", "curses", "daemon", "test"])

        except getopt.GetoptError:
            self.usage()
            sys.exit(2)

        for opt, _ in opts:
            if opt in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif opt in ("-d", "--daemon"):
                daemon = True
            elif opt in ("-c", "--curses"):
                state.curses = True
            elif opt in ("-t", "--test"):
                state.testmode = True
                if os.path.isfile(os.path.join(
                        state.appdata, 'unittest.lock')):
                    daemon = True
                state.enableGUI = False  # run without a UI
                # Fallback: in case when no api command was issued
                state.last_api_response = time.time()
                # Apply special settings
                config.set(
                    'bitmessagesettings', 'apienabled', 'true')
                config.set(
                    'bitmessagesettings', 'apiusername', 'username')
                config.set(
                    'bitmessagesettings', 'apipassword', 'password')
                config.set(
                    'bitmessagesettings', 'apinotifypath',
                    os.path.join(app_dir, 'tests', 'apinotify_handler.py')
                )

        if daemon:
            state.enableGUI = False  # run without a UI

        if state.enableGUI and not state.curses and not depends.check_pyqt():
            sys.exit(
                'PyBitmessage requires PyQt unless you want'
                ' to run it as a daemon and interact with it'
                ' using the API. You can download PyQt from '
                'http://www.riverbankcomputing.com/software/pyqt/download'
                ' or by searching Google for \'PyQt Download\'.'
                ' If you want to run in daemon mode, see '
                'https://bitmessage.org/wiki/Daemon\n'
                'You can also run PyBitmessage with'
                ' the new curses interface by providing'
                ' \'-c\' as a commandline argument.'
            )
        # is the application already running?  If yes then exit.
        state.thisapp = singleinstance("", daemon)

        if daemon:
            with printLock:
                print('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        set_thread_name("PyBitmessage")

        state.dandelion = config.safeGetInt('network', 'dandelion')
        # dandelion requires outbound connections, without them,
        # stem objects will get stuck forever
        if state.dandelion and not config.safeGetBoolean(
                'bitmessagesettings', 'sendoutgoingconnections'):
            state.dandelion = 0

        if state.testmode or config.safeGetBoolean(
                'bitmessagesettings', 'extralowdifficulty'):
            defaults.networkDefaultProofOfWorkNonceTrialsPerByte = int(
                defaults.networkDefaultProofOfWorkNonceTrialsPerByte / 100)
            defaults.networkDefaultPayloadLengthExtraBytes = int(
                defaults.networkDefaultPayloadLengthExtraBytes / 100)

        readKnownNodes()

        # Not needed if objproc is disabled
        if state.enableObjProc:

            # Start the address generation thread
            addressGeneratorThread = addressGenerator()
            # close the main program even if there are threads left
            addressGeneratorThread.daemon = True
            addressGeneratorThread.start()

            # Start the thread that calculates POWs
            singleWorkerThread = singleWorker()
            # close the main program even if there are threads left
            singleWorkerThread.daemon = True
            singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        # DON'T close the main program even if there are threads left.
        # The closeEvent should command this thread to exit gracefully.
        sqlLookup.daemon = False
        sqlLookup.start()

        Inventory()  # init
        # init, needs to be early because other thread may access it early
        Dandelion()

        # Enable object processor and SMTP only if objproc enabled
        if state.enableObjProc:

            # SMTP delivery thread
            if daemon and config.safeGet(
                    'bitmessagesettings', 'smtpdeliver', '') != '':
                from class_smtpDeliver import smtpDeliver
                smtpDeliveryThread = smtpDeliver()
                smtpDeliveryThread.start()

            # SMTP daemon thread
            if daemon and config.safeGetBoolean(
                    'bitmessagesettings', 'smtpd'):
                from class_smtpServer import smtpServer
                smtpServerThread = smtpServer()
                smtpServerThread.start()

            # Start the thread that calculates POWs
            objectProcessorThread = objectProcessor()
            # DON'T close the main program even the thread remains.
            # This thread checks the shutdown variable after processing
            # each object.
            objectProcessorThread.daemon = False
            objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        # close the main program even if there are threads left
        singleCleanerThread.daemon = True
        singleCleanerThread.start()

        # Not needed if objproc disabled
        if state.enableObjProc:
            shared.reloadMyAddressHashes()
            shared.reloadBroadcastSendersForWhichImWatching()

            # API is also objproc dependent
            if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
                import api  # pylint: disable=relative-import
                singleAPIThread = api.singleAPI()
                # close the main program even if there are threads left
                singleAPIThread.daemon = True
                singleAPIThread.start()

        # start network components if networking is enabled
        if state.enableNetwork:
            start_proxyconfig()
            BMConnectionPool().connectToStream(1)
            asyncoreThread = BMNetworkThread()
            asyncoreThread.daemon = True
            asyncoreThread.start()
            for i in range(config.getint('threads', 'receive')):
                receiveQueueThread = ReceiveQueueThread(i)
                receiveQueueThread.daemon = True
                receiveQueueThread.start()
            announceThread = AnnounceThread()
            announceThread.daemon = True
            announceThread.start()
            state.invThread = InvThread()
            state.invThread.daemon = True
            state.invThread.start()
            state.addrThread = AddrThread()
            state.addrThread.daemon = True
            state.addrThread.start()
            state.downloadThread = DownloadThread()
            state.downloadThread.daemon = True
            state.downloadThread.start()
            state.uploadThread = UploadThread()
            state.uploadThread.daemon = True
            state.uploadThread.start()

            if config.safeGetBoolean('bitmessagesettings', 'upnp'):
                import upnp
                upnpThread = upnp.uPnPThread()
                upnpThread.start()
        else:
            # Populate with hardcoded value (same as connectToStream above)
            state.streamsInWhichIAmParticipating.append(1)

        if not daemon and state.enableGUI:
            if state.curses:
                if not depends.check_curses():
                    sys.exit()
                print('Running with curses')
                import bitmessagecurses
                bitmessagecurses.runwrapper()
            elif state.kivy:
                config.remove_option('bitmessagesettings', 'dontconnect')
                from bitmessagekivy.mpybit import NavigateApp
                NavigateApp().run()
            else:
                import bitmessageqt
                bitmessageqt.run()
        else:
            config.remove_option('bitmessagesettings', 'dontconnect')

        if daemon:
            while state.shutdown == 0:
                time.sleep(1)
                if (
                    state.testmode
                    and time.time() - state.last_api_response >= 30
                ):
                    self.stop()
        elif not state.enableGUI:
            state.enableGUI = True
            # pylint: disable=relative-import
            from tests import core as test_core
            test_core_result = test_core.run()
            state.enableGUI = True
            self.stop()
            test_core.cleanup()
            sys.exit(
                'Core tests failed!'
                if test_core_result.errors or test_core_result.failures
                else 0
            )
Exemplo n.º 3
0
    def start(self):
        _fixSocket()

        daemon = BMConfigParser().safeGetBoolean('bitmessagesettings',
                                                 'daemon')

        try:
            opts, args = getopt.getopt(sys.argv[1:], "hcd",
                                       ["help", "curses", "daemon"])

        except getopt.GetoptError:
            self.usage()
            sys.exit(2)

        for opt, arg in opts:
            if opt in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif opt in ("-d", "--daemon"):
                daemon = True
            elif opt in ("-c", "--curses"):
                state.curses = True

        # is the application already running?  If yes then exit.
        shared.thisapp = singleinstance("", daemon)

        if daemon:
            with shared.printLock:
                print('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        helper_threading.set_thread_name("PyBitmessage")

        state.dandelion = BMConfigParser().safeGetInt('network', 'dandelion')
        # dandelion requires outbound connections, without them, stem objects will get stuck forever
        if state.dandelion and not BMConfigParser().safeGetBoolean(
                'bitmessagesettings', 'sendoutgoingconnections'):
            state.dandelion = 0

        helper_bootstrap.knownNodes()
        # Start the address generation thread
        addressGeneratorThread = addressGenerator()
        addressGeneratorThread.daemon = True  # close the main program even if there are threads left
        addressGeneratorThread.start()

        # Start the thread that calculates POWs
        singleWorkerThread = singleWorker()
        singleWorkerThread.daemon = True  # close the main program even if there are threads left
        singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        sqlLookup.daemon = False  # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
        sqlLookup.start()

        Inventory()  # init
        Dandelion(
        )  # init, needs to be early because other thread may access it early

        # SMTP delivery thread
        if daemon and BMConfigParser().safeGet("bitmessagesettings",
                                               "smtpdeliver", '') != '':
            smtpDeliveryThread = smtpDeliver()
            smtpDeliveryThread.start()

        # SMTP daemon thread
        if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings",
                                                      "smtpd"):
            smtpServerThread = smtpServer()
            smtpServerThread.start()

        # Start the thread that calculates POWs
        objectProcessorThread = objectProcessor()
        objectProcessorThread.daemon = False  # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
        objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        singleCleanerThread.daemon = True  # close the main program even if there are threads left
        singleCleanerThread.start()

        shared.reloadMyAddressHashes()
        shared.reloadBroadcastSendersForWhichImWatching()

        if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
            try:
                apiNotifyPath = BMConfigParser().get('bitmessagesettings',
                                                     'apinotifypath')
            except:
                apiNotifyPath = ''
            if apiNotifyPath != '':
                with shared.printLock:
                    print('Trying to call', apiNotifyPath)

                call([apiNotifyPath, "startingUp"])
            singleAPIThread = singleAPI()
            singleAPIThread.daemon = True  # close the main program even if there are threads left
            singleAPIThread.start()

        BMConnectionPool()
        asyncoreThread = BMNetworkThread()
        asyncoreThread.daemon = True
        asyncoreThread.start()
        for i in range(BMConfigParser().getint("threads", "receive")):
            receiveQueueThread = ReceiveQueueThread(i)
            receiveQueueThread.daemon = True
            receiveQueueThread.start()
        announceThread = AnnounceThread()
        announceThread.daemon = True
        announceThread.start()
        state.invThread = InvThread()
        state.invThread.daemon = True
        state.invThread.start()
        state.addrThread = AddrThread()
        state.addrThread.daemon = True
        state.addrThread.start()
        state.downloadThread = DownloadThread()
        state.downloadThread.daemon = True
        state.downloadThread.start()

        connectToStream(1)

        if BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp'):
            import upnp
            upnpThread = upnp.uPnPThread()
            upnpThread.start()

        if daemon == False and BMConfigParser().safeGetBoolean(
                'bitmessagesettings', 'daemon') == False:
            if state.curses == False:
                if not depends.check_pyqt():
                    print(
                        'PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download   or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon'
                    )
                    print(
                        'You can also run PyBitmessage with the new curses interface by providing \'-c\' as a commandline argument.'
                    )
                    sys.exit()

                import bitmessageqt
                bitmessageqt.run()
            else:
                if True:
                    #                if depends.check_curses():
                    print('Running with curses')
                    import bitmessagecurses
                    bitmessagecurses.runwrapper()
        else:
            BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')

        if daemon:
            while state.shutdown == 0:
                sleep(1)
Exemplo n.º 4
0
    def start(self, daemon=False):
        global thisapp
        
        _fixWinsock()

        shared.daemon = daemon
        # is the application already running?  If yes then exit.
        thisapp = singleton.singleinstance("", daemon)

        # get curses flag
        curses = False
        if '-c' in sys.argv:
            curses = True

        signal.signal(signal.SIGINT, helper_generic.signal_handler)
        # signal.signal(signal.SIGINT, signal.SIG_DFL)

        helper_bootstrap.knownNodes()
        # Start the address generation thread
        addressGeneratorThread = addressGenerator()
        addressGeneratorThread.daemon = True  # close the main program even if there are threads left
        addressGeneratorThread.start()

        # Start the thread that calculates POWs
        singleWorkerThread = singleWorker()
        singleWorkerThread.daemon = True  # close the main program even if there are threads left
        singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        sqlLookup.daemon = False  # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
        sqlLookup.start()

        # Start the thread that calculates POWs
        objectProcessorThread = objectProcessor()
        objectProcessorThread.daemon = False  # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
        objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        singleCleanerThread.daemon = True  # close the main program even if there are threads left
        singleCleanerThread.start()

        shared.reloadMyAddressHashes()
        shared.reloadBroadcastSendersForWhichImWatching()

        if shared.safeConfigGetBoolean('bitmessagesettings', 'apienabled'):
            try:
                apiNotifyPath = shared.config.get(
                    'bitmessagesettings', 'apinotifypath')
            except:
                apiNotifyPath = ''
            if apiNotifyPath != '':
                with shared.printLock:
                    print('Trying to call', apiNotifyPath)

                call([apiNotifyPath, "startingUp"])
            singleAPIThread = singleAPI()
            singleAPIThread.daemon = True  # close the main program even if there are threads left
            singleAPIThread.start()

        connectToStream(1)

        singleListenerThread = singleListener()
        singleListenerThread.setup(selfInitiatedConnections)
        singleListenerThread.daemon = True  # close the main program even if there are threads left
        singleListenerThread.start()
        
        if shared.safeConfigGetBoolean('bitmessagesettings','upnp'):
            import upnp
            upnpThread = upnp.uPnPThread()
            upnpThread.start()

        if daemon == False and shared.safeConfigGetBoolean('bitmessagesettings', 'daemon') == False:
            if curses == False:
                if not depends.check_pyqt():
                    print('PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download   or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
                    print('You can also run PyBitmessage with the new curses interface by providing \'-c\' as a commandline argument.')
                    sys.exit()

                import bitmessageqt
                bitmessageqt.run()
            else:
                if depends.check_curses():
                    print('Running with curses')
                    import bitmessagecurses
                    bitmessagecurses.runwrapper()
        else:
            shared.config.remove_option('bitmessagesettings', 'dontconnect')

            if daemon:
                with shared.printLock:
                    print('Running as a daemon. The main program should exit this thread.')
            else:
                with shared.printLock:
                    print('Running as a daemon. You can use Ctrl+C to exit.')
                while True:
                    time.sleep(20)
Exemplo n.º 5
0
    def start(self):
        _fixSocket()

        daemon = BMConfigParser().safeGetBoolean('bitmessagesettings',
                                                 'daemon')

        try:
            opts, args = getopt.getopt(sys.argv[1:], "hcdt",
                                       ["help", "curses", "daemon", "test"])

        except getopt.GetoptError:
            self.usage()
            sys.exit(2)

        for opt, arg in opts:
            if opt in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif opt in ("-d", "--daemon"):
                daemon = True
                state.enableGUI = False  # run without a UI
            elif opt in ("-c", "--curses"):
                state.curses = True
            elif opt in ("-t", "--test"):
                state.testmode = True
                if os.path.isfile(os.path.join(state.appdata,
                                               'unittest.lock')):
                    daemon = True
                state.enableGUI = False  # run without a UI
                # Fallback: in case when no api command was issued
                state.last_api_response = datetime.now()
                # Apply special settings
                config = BMConfigParser()
                config.set('bitmessagesettings', 'apienabled', 'true')
                config.set('bitmessagesettings', 'apiusername', 'username')
                config.set('bitmessagesettings', 'apipassword', 'password')
                config.set(
                    'bitmessagesettings', 'apinotifypath',
                    os.path.join(app_dir, 'tests', 'apinotify_handler.py'))

        # is the application already running?  If yes then exit.
        shared.thisapp = singleinstance("", daemon)

        if daemon:
            with shared.printLock:
                print('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        helper_threading.set_thread_name("PyBitmessage")

        state.dandelion = BMConfigParser().safeGetInt('network', 'dandelion')
        # dandelion requires outbound connections, without them, stem objects will get stuck forever
        if state.dandelion and not BMConfigParser().safeGetBoolean(
                'bitmessagesettings', 'sendoutgoingconnections'):
            state.dandelion = 0

        helper_bootstrap.knownNodes()

        # Not needed if objproc is disabled
        if state.enableObjProc:

            # Start the address generation thread
            addressGeneratorThread = addressGenerator()
            addressGeneratorThread.daemon = True  # close the main program even if there are threads left
            addressGeneratorThread.start()

            # Start the thread that calculates POWs
            singleWorkerThread = singleWorker()
            singleWorkerThread.daemon = True  # close the main program even if there are threads left
            singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        sqlLookup.daemon = False  # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
        sqlLookup.start()

        Inventory()  # init
        Dandelion(
        )  # init, needs to be early because other thread may access it early

        # Enable object processor and SMTP only if objproc enabled
        if state.enableObjProc:

            # SMTP delivery thread
            if daemon and BMConfigParser().safeGet("bitmessagesettings",
                                                   "smtpdeliver", '') != '':
                smtpDeliveryThread = smtpDeliver()
                smtpDeliveryThread.start()

            # SMTP daemon thread
            if daemon and BMConfigParser().safeGetBoolean(
                    "bitmessagesettings", "smtpd"):
                smtpServerThread = smtpServer()
                smtpServerThread.start()

            # Start the thread that calculates POWs
            objectProcessorThread = objectProcessor()
            objectProcessorThread.daemon = False  # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
            objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        singleCleanerThread.daemon = True  # close the main program even if there are threads left
        singleCleanerThread.start()

        # Not needed if objproc disabled
        if state.enableObjProc:
            shared.reloadMyAddressHashes()
            shared.reloadBroadcastSendersForWhichImWatching()

            # API is also objproc dependent
            if BMConfigParser().safeGetBoolean('bitmessagesettings',
                                               'apienabled'):
                singleAPIThread = singleAPI()
                singleAPIThread.daemon = True  # close the main program even if there are threads left
                singleAPIThread.start()

        # start network components if networking is enabled
        if state.enableNetwork:
            BMConnectionPool()
            asyncoreThread = BMNetworkThread()
            asyncoreThread.daemon = True
            asyncoreThread.start()
            for i in range(BMConfigParser().getint("threads", "receive")):
                receiveQueueThread = ReceiveQueueThread(i)
                receiveQueueThread.daemon = True
                receiveQueueThread.start()
            announceThread = AnnounceThread()
            announceThread.daemon = True
            announceThread.start()
            state.invThread = InvThread()
            state.invThread.daemon = True
            state.invThread.start()
            state.addrThread = AddrThread()
            state.addrThread.daemon = True
            state.addrThread.start()
            state.downloadThread = DownloadThread()
            state.downloadThread.daemon = True
            state.downloadThread.start()

            connectToStream(1)

            if BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp'):
                import upnp
                upnpThread = upnp.uPnPThread()
                upnpThread.start()
        else:
            # Populate with hardcoded value (same as connectToStream above)
            state.streamsInWhichIAmParticipating.append(1)

        if daemon is False and state.enableGUI:  # FIXME redundant?
            if state.curses is False:
                if not depends.check_pyqt():
                    sys.exit(
                        'PyBitmessage requires PyQt unless you want'
                        ' to run it as a daemon and interact with it'
                        ' using the API. You can download PyQt from '
                        'http://www.riverbankcomputing.com/software/pyqt/download'
                        ' or by searching Google for \'PyQt Download\'.'
                        ' If you want to run in daemon mode, see '
                        'https://bitmessage.org/wiki/Daemon\n'
                        'You can also run PyBitmessage with'
                        ' the new curses interface by providing'
                        ' \'-c\' as a commandline argument.')

                import bitmessageqt
                bitmessageqt.run()
            else:
                if True:
                    #                if depends.check_curses():
                    print('Running with curses')
                    import bitmessagecurses
                    bitmessagecurses.runwrapper()
        else:
            BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')

        if daemon:
            while state.shutdown == 0:
                sleep(1)
                if state.testmode and 30 <= \
                        (datetime.now() - state.last_api_response).seconds:
                    self.stop()
        elif not state.enableGUI:
            from tests import core
            test_core_result = core.run()
            state.enableGUI = True
            self.stop()
            sys.exit('Core tests failed!' if test_core_result.errors
                     or test_core_result.failures else 0)
Exemplo n.º 6
0
    def start(self):
        _fixSocket()

        daemon = BMConfigParser().safeGetBoolean(
            'bitmessagesettings', 'daemon')

        try:
            opts, args = getopt.getopt(
                sys.argv[1:], "hcdtsa",
                ["help", "curses", "daemon", "test", "apitest"])

        except getopt.GetoptError:
            self.usage()
            sys.exit(2)

        for opt, arg in opts:
            if opt in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif opt in ("-d", "--daemon"):
                daemon = True
                state.enableGUI = False  # run without a UI
            elif opt in ("-c", "--curses"):
                state.curses = True
            elif opt in ("-t", "--test"):
                state.testmode = daemon = True
                state.enableGUI = False  # run without a UI
            elif opt in ("-a", "--apitest"):
                from bmsxmlrpc.server import TestAPIThread
                server = TestAPIThread()
                server.start()

        # is the application already running?  If yes then exit.
        if state.enableGUI and not state.curses and not depends.check_pyqt():
            sys.exit(
                'PyBitmessage requires PyQt unless you want'
                ' to run it as a daemon and interact with it'
                ' using the API. You can download PyQt from '
                'http://www.riverbankcomputing.com/software/pyqt/download'
                ' or by searching Google for \'PyQt Download\'.'
                ' If you want to run in daemon mode, see '
                'https://bitmessage.org/wiki/Daemon\n'
                'You can also run PyBitmessage with'
                ' the new curses interface by providing'
                ' \'-c\' as a commandline argument.'
            )
        shared.thisapp = singleinstance("", daemon)

        if daemon and not state.testmode:
            with shared.printLock:
                logger.warn('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        helper_threading.set_thread_name("PyBitmessage")

        state.dandelion = BMConfigParser().safeGetInt('network', 'dandelion')
        # dandelion requires outbound connections, without them,
        # stem objects will get stuck forever
        if state.dandelion and not BMConfigParser().safeGetBoolean(
                'bitmessagesettings', 'sendoutgoingconnections'):
            state.dandelion = 0

        knownnodes.readKnownNodes()

        # Not needed if objproc is disabled
        if state.enableObjProc:

            # Start the address generation thread
            addressGeneratorThread = addressGenerator()
            # close the main program even if there are threads left
            addressGeneratorThread.daemon = True
            addressGeneratorThread.start()

            # Start the thread that calculates POWs
            singleWorkerThread = singleWorker()
            # close the main program even if there are threads left
            singleWorkerThread.daemon = True
            singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        # DON'T close the main program even if there are threads left.
        # The closeEvent should command this thread to exit gracefully.
        sqlLookup.daemon = False
        sqlLookup.start()

        Inventory()  # init
        # init, needs to be early because other thread may access it early
        Dandelion()

        # Enable object processor and SMTP only if objproc enabled
        if state.enableObjProc:

            # SMTP delivery thread
            if daemon and BMConfigParser().safeGet(
                    "bitmessagesettings", "smtpdeliver", '') != '':
                from class_smtpDeliver import smtpDeliver
                smtpDeliveryThread = smtpDeliver()
                smtpDeliveryThread.start()

            # SMTP daemon thread
            if daemon and BMConfigParser().safeGetBoolean(
                    "bitmessagesettings", "smtpd"):
                from class_smtpServer import smtpServer
                smtpServerThread = smtpServer()
                smtpServerThread.start()

            # Start the thread that calculates POWs
            objectProcessorThread = objectProcessor()
            # DON'T close the main program even the thread remains.
            # This thread checks the shutdown variable after processing
            # each object.
            objectProcessorThread.daemon = False
            objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        # close the main program even if there are threads left
        singleCleanerThread.daemon = True
        singleCleanerThread.start()

        # Not needed if objproc disabled
        if state.enableObjProc:
            shared.reloadMyAddressHashes()
            shared.reloadBroadcastSendersForWhichImWatching()

            # API is also objproc dependent
            if BMConfigParser().safeGetBoolean(
                    'bitmessagesettings', 'apienabled'):
                try:
                    apiNotifyPath = BMConfigParser().get(
                        'bitmessagesettings', 'apinotifypath')
                except:
                    apiNotifyPath = ''
                if apiNotifyPath != '':
                    with shared.printLock:
                        print('Trying to call', apiNotifyPath)

                    call([apiNotifyPath, "startingUp"])
                from bmsxmlrpc.server import singleAPI
                singleAPIThread = singleAPI()
                # close the main program even if there are threads left
                singleAPIThread.daemon = True
                singleAPIThread.start()

        # start network components if networking is enabled
        if state.enableNetwork:
            BMConnectionPool()
            asyncoreThread = BMNetworkThread()
            asyncoreThread.daemon = True
            asyncoreThread.start()
            for i in range(BMConfigParser().getint("threads", "receive")):
                receiveQueueThread = ReceiveQueueThread(i)
                receiveQueueThread.daemon = True
                receiveQueueThread.start()
            announceThread = AnnounceThread()
            announceThread.daemon = True
            announceThread.start()
            state.invThread = InvThread()
            state.invThread.daemon = True
            state.invThread.start()
            state.addrThread = AddrThread()
            state.addrThread.daemon = True
            state.addrThread.start()
            state.downloadThread = DownloadThread()
            state.downloadThread.daemon = True
            state.downloadThread.start()

            connectToStream(1)

            if BMConfigParser().safeGetBoolean(
                    'bitmessagesettings', 'upnp'):
                import upnp
                upnpThread = upnp.uPnPThread()
                upnpThread.start()
        else:
            # Populate with hardcoded value (same as connectToStream above)
            state.streamsInWhichIAmParticipating.append(1)

        if not daemon and state.enableGUI:
            if state.curses:
                if not depends.check_curses():
                    sys.exit()
                logger.info('Running with curses')
                import bitmessagecurses
                bitmessagecurses.runwrapper()
            elif state.kivy:
                BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
                from bitmessagekivy.mpybit import NavigateApp
                NavigateApp().run()
            else:
                import bitmessageqt
                bitmessageqt.run()
        else:
            BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')

        if daemon:
            if state.testmode:
                sleep(30)
                # make testing
                self.stop()
            while state.shutdown == 0:
                sleep(1)
Exemplo n.º 7
0
    def accept(self):
        """A callback for accepted event of buttonBox (OK button pressed)"""
        # pylint: disable=too-many-branches,too-many-statements
        super(SettingsDialog, self).accept()
        if self.firstrun:
            self.config.remove_option('bitmessagesettings', 'dontconnect')
        self.config.set('bitmessagesettings', 'startonlogon',
                        str(self.checkBoxStartOnLogon.isChecked()))
        self.config.set('bitmessagesettings', 'minimizetotray',
                        str(self.checkBoxMinimizeToTray.isChecked()))
        self.config.set('bitmessagesettings', 'trayonclose',
                        str(self.checkBoxTrayOnClose.isChecked()))
        self.config.set(
            'bitmessagesettings', 'hidetrayconnectionnotifications',
            str(self.checkBoxHideTrayConnectionNotifications.isChecked()))
        self.config.set('bitmessagesettings', 'showtraynotifications',
                        str(self.checkBoxShowTrayNotifications.isChecked()))
        self.config.set('bitmessagesettings', 'startintray',
                        str(self.checkBoxStartInTray.isChecked()))
        self.config.set('bitmessagesettings', 'willinglysendtomobile',
                        str(self.checkBoxWillinglySendToMobile.isChecked()))
        self.config.set('bitmessagesettings', 'useidenticons',
                        str(self.checkBoxUseIdenticons.isChecked()))
        self.config.set('bitmessagesettings', 'replybelow',
                        str(self.checkBoxReplyBelow.isChecked()))

        lang = str(
            self.languageComboBox.itemData(
                self.languageComboBox.currentIndex()).toString())
        self.config.set('bitmessagesettings', 'userlocale', lang)
        self.parent.change_translation()

        if int(self.config.get('bitmessagesettings', 'port')) != int(
                self.lineEditTCPPort.text()):
            self.config.set('bitmessagesettings', 'port',
                            str(self.lineEditTCPPort.text()))
            if not self.config.safeGetBoolean('bitmessagesettings',
                                              'dontconnect'):
                self.net_restart_needed = True

        if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean(
                'bitmessagesettings', 'upnp'):
            self.config.set('bitmessagesettings', 'upnp',
                            str(self.checkBoxUPnP.isChecked()))
            if self.checkBoxUPnP.isChecked():
                import upnp
                upnpThread = upnp.uPnPThread()
                upnpThread.start()

        proxytype_index = self.comboBoxProxyType.currentIndex()
        if proxytype_index == 0:
            if self._proxy_type and state.statusIconColor != 'red':
                self.net_restart_needed = True
        elif self.comboBoxProxyType.currentText() != self._proxy_type:
            self.net_restart_needed = True
            self.parent.statusbar.clearMessage()

        self.config.set(
            'bitmessagesettings', 'socksproxytype',
            'none' if self.comboBoxProxyType.currentIndex() == 0 else str(
                self.comboBoxProxyType.currentText()))
        if proxytype_index > 2:  # last literal proxytype in ui
            start_proxyconfig()

        self.config.set('bitmessagesettings', 'socksauthentication',
                        str(self.checkBoxAuthentication.isChecked()))
        self.config.set('bitmessagesettings', 'sockshostname',
                        str(self.lineEditSocksHostname.text()))
        self.config.set('bitmessagesettings', 'socksport',
                        str(self.lineEditSocksPort.text()))
        self.config.set('bitmessagesettings', 'socksusername',
                        str(self.lineEditSocksUsername.text()))
        self.config.set('bitmessagesettings', 'sockspassword',
                        str(self.lineEditSocksPassword.text()))
        self.config.set('bitmessagesettings', 'sockslisten',
                        str(self.checkBoxSocksListen.isChecked()))
        if self.checkBoxOnionOnly.isChecked() \
                and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'):
            self.net_restart_needed = True
        self.config.set('bitmessagesettings', 'onionservicesonly',
                        str(self.checkBoxOnionOnly.isChecked()))
        try:
            # Rounding to integers just for aesthetics
            self.config.set(
                'bitmessagesettings', 'maxdownloadrate',
                str(int(float(self.lineEditMaxDownloadRate.text()))))
            self.config.set('bitmessagesettings', 'maxuploadrate',
                            str(int(float(self.lineEditMaxUploadRate.text()))))
        except ValueError:
            QtGui.QMessageBox.about(
                self, _translate("MainWindow", "Number needed"),
                _translate(
                    "MainWindow",
                    "Your maximum download and upload rate must be numbers."
                    " Ignoring what you typed."))
        else:
            set_rates(
                self.config.safeGetInt('bitmessagesettings',
                                       'maxdownloadrate'),
                self.config.safeGetInt('bitmessagesettings', 'maxuploadrate'))

        self.config.set(
            'bitmessagesettings', 'maxoutboundconnections',
            str(int(float(self.lineEditMaxOutboundConnections.text()))))

        self.config.set('bitmessagesettings', 'namecoinrpctype',
                        self.getNamecoinType())
        self.config.set('bitmessagesettings', 'namecoinrpchost',
                        str(self.lineEditNamecoinHost.text()))
        self.config.set('bitmessagesettings', 'namecoinrpcport',
                        str(self.lineEditNamecoinPort.text()))
        self.config.set('bitmessagesettings', 'namecoinrpcuser',
                        str(self.lineEditNamecoinUser.text()))
        self.config.set('bitmessagesettings', 'namecoinrpcpassword',
                        str(self.lineEditNamecoinPassword.text()))
        self.parent.resetNamecoinConnection()

        # Demanded difficulty tab
        if float(self.lineEditTotalDifficulty.text()) >= 1:
            self.config.set(
                'bitmessagesettings', 'defaultnoncetrialsperbyte',
                str(
                    int(
                        float(self.lineEditTotalDifficulty.text()) *
                        defaults.networkDefaultProofOfWorkNonceTrialsPerByte)))
        if float(self.lineEditSmallMessageDifficulty.text()) >= 1:
            self.config.set(
                'bitmessagesettings', 'defaultpayloadlengthextrabytes',
                str(
                    int(
                        float(self.lineEditSmallMessageDifficulty.text()) *
                        defaults.networkDefaultPayloadLengthExtraBytes)))

        if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet(
                'bitmessagesettings', 'opencl'):
            self.config.set('bitmessagesettings', 'opencl',
                            str(self.comboBoxOpenCL.currentText()))
            queues.workerQueue.put(('resetPoW', ''))

        acceptableDifficultyChanged = False

        if (float(self.lineEditMaxAcceptableTotalDifficulty.text()) >= 1 or
                float(self.lineEditMaxAcceptableTotalDifficulty.text()) == 0):
            if self.config.get(
                    'bitmessagesettings', 'maxacceptablenoncetrialsperbyte'
            ) != str(
                    int(
                        float(
                            self.lineEditMaxAcceptableTotalDifficulty.text()) *
                        defaults.networkDefaultProofOfWorkNonceTrialsPerByte)):
                # the user changed the max acceptable total difficulty
                acceptableDifficultyChanged = True
                self.config.set(
                    'bitmessagesettings', 'maxacceptablenoncetrialsperbyte',
                    str(
                        int(
                            float(self.lineEditMaxAcceptableTotalDifficulty.
                                  text()) * defaults.
                            networkDefaultProofOfWorkNonceTrialsPerByte)))
        if (float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) >= 1
                or float(
                    self.lineEditMaxAcceptableSmallMessageDifficulty.text())
                == 0):
            if self.config.get(
                    'bitmessagesettings',
                    'maxacceptablepayloadlengthextrabytes'
            ) != str(
                    int(
                        float(self.lineEditMaxAcceptableSmallMessageDifficulty.
                              text()) *
                        defaults.networkDefaultPayloadLengthExtraBytes)):
                # the user changed the max acceptable small message difficulty
                acceptableDifficultyChanged = True
                self.config.set(
                    'bitmessagesettings',
                    'maxacceptablepayloadlengthextrabytes',
                    str(
                        int(
                            float(self.
                                  lineEditMaxAcceptableSmallMessageDifficulty.
                                  text()) *
                            defaults.networkDefaultPayloadLengthExtraBytes)))
        if acceptableDifficultyChanged:
            # It might now be possible to send msgs which were previously
            # marked as toodifficult. Let us change them to 'msgqueued'.
            # The singleWorker will try to send them and will again mark
            # them as toodifficult if the receiver's required difficulty
            # is still higher than we are willing to do.
            sqlExecute("UPDATE sent SET status='msgqueued'"
                       " WHERE status='toodifficult'")
            queues.workerQueue.put(('sendmessage', ''))

        stopResendingDefaults = False

        # UI setting to stop trying to send messages after X days/months
        # I'm open to changing this UI to something else if someone has a better idea.
        if self.lineEditDays.text() == '' and self.lineEditMonths.text() == '':
            # We need to handle this special case. Bitmessage has its
            # default behavior. The input is blank/blank
            self.config.set('bitmessagesettings', 'stopresendingafterxdays',
                            '')
            self.config.set('bitmessagesettings', 'stopresendingafterxmonths',
                            '')
            state.maximumLengthOfTimeToBotherResendingMessages = float('inf')
            stopResendingDefaults = True

        try:
            days = float(self.lineEditDays.text())
        except ValueError:
            self.lineEditDays.setText("0")
            days = 0.0
        try:
            months = float(self.lineEditMonths.text())
        except ValueError:
            self.lineEditMonths.setText("0")
            months = 0.0

        if days >= 0 and months >= 0 and not stopResendingDefaults:
            state.maximumLengthOfTimeToBotherResendingMessages = \
                days * 24 * 60 * 60 + months * 60 * 60 * 24 * 365 / 12
            if state.maximumLengthOfTimeToBotherResendingMessages < 432000:
                # If the time period is less than 5 hours, we give
                # zero values to all fields. No message will be sent again.
                QtGui.QMessageBox.about(
                    self, _translate("MainWindow", "Will not resend ever"),
                    _translate(
                        "MainWindow",
                        "Note that the time limit you entered is less"
                        " than the amount of time Bitmessage waits for"
                        " the first resend attempt therefore your"
                        " messages will never be resent."))
                self.config.set('bitmessagesettings',
                                'stopresendingafterxdays', '0')
                self.config.set('bitmessagesettings',
                                'stopresendingafterxmonths', '0')
                state.maximumLengthOfTimeToBotherResendingMessages = 0.0
            else:
                self.config.set('bitmessagesettings',
                                'stopresendingafterxdays', str(days))
                self.config.set('bitmessagesettings',
                                'stopresendingafterxmonths', str(months))

        self.config.save()

        if self.net_restart_needed:
            self.net_restart_needed = False
            self.config.setTemp('bitmessagesettings', 'dontconnect', 'true')
            self.timer.singleShot(
                5000, lambda: self.config.setTemp('bitmessagesettings',
                                                  'dontconnect', 'false'))

        self.parent.updateStartOnLogon()

        if (state.appdata != paths.lookupExeFolder()
                and self.checkBoxPortableMode.isChecked()):
            # If we are NOT using portable mode now but the user selected
            # that we should...
            # Write the keys.dat file to disk in the new location
            sqlStoredProcedure('movemessagstoprog')
            with open(paths.lookupExeFolder() + 'keys.dat',
                      'wb') as configfile:
                self.config.write(configfile)
            # Write the knownnodes.dat file to disk in the new location
            knownnodes.saveKnownNodes(paths.lookupExeFolder())
            os.remove(state.appdata + 'keys.dat')
            os.remove(state.appdata + 'knownnodes.dat')
            previousAppdataLocation = state.appdata
            state.appdata = paths.lookupExeFolder()
            debug.resetLogging()
            try:
                os.remove(previousAppdataLocation + 'debug.log')
                os.remove(previousAppdataLocation + 'debug.log.1')
            except Exception:
                pass

        if (state.appdata == paths.lookupExeFolder()
                and not self.checkBoxPortableMode.isChecked()):
            # If we ARE using portable mode now but the user selected
            # that we shouldn't...
            state.appdata = paths.lookupAppdataFolder()
            if not os.path.exists(state.appdata):
                os.makedirs(state.appdata)
            sqlStoredProcedure('movemessagstoappdata')
            # Write the keys.dat file to disk in the new location
            self.config.save()
            # Write the knownnodes.dat file to disk in the new location
            knownnodes.saveKnownNodes(state.appdata)
            os.remove(paths.lookupExeFolder() + 'keys.dat')
            os.remove(paths.lookupExeFolder() + 'knownnodes.dat')
            debug.resetLogging()
            try:
                os.remove(paths.lookupExeFolder() + 'debug.log')
                os.remove(paths.lookupExeFolder() + 'debug.log.1')
            except Exception:
                pass
Exemplo n.º 8
0
    def start(self):
        _fixSocket()

        daemon = BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon')

        try:
            opts, args = getopt.getopt(sys.argv[1:], "hcd",
                ["help", "curses", "daemon"])

        except getopt.GetoptError:
            self.usage()
            sys.exit(2)

        for opt, arg in opts:
            if opt in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif opt in ("-d", "--daemon"):
                daemon = True
            elif opt in ("-c", "--curses"):
                state.curses = True

        shared.daemon = daemon

        # is the application already running?  If yes then exit.
        shared.thisapp = singleinstance("", daemon)

        if daemon:
            with shared.printLock:
                print('Running as a daemon. Send TERM signal to end.')
            self.daemonize()

        self.setSignalHandler()

        helper_threading.set_thread_name("PyBitmessage")

        helper_bootstrap.knownNodes()
        # Start the address generation thread
        addressGeneratorThread = addressGenerator()
        addressGeneratorThread.daemon = True  # close the main program even if there are threads left
        addressGeneratorThread.start()

        # Start the thread that calculates POWs
        singleWorkerThread = singleWorker()
        singleWorkerThread.daemon = True  # close the main program even if there are threads left
        singleWorkerThread.start()

        # Start the SQL thread
        sqlLookup = sqlThread()
        sqlLookup.daemon = False  # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
        sqlLookup.start()

        Inventory() # init
        Dandelion() # init, needs to be early because other thread may access it early

        # SMTP delivery thread
        if daemon and BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '') != '':
            smtpDeliveryThread = smtpDeliver()
            smtpDeliveryThread.start()

        # SMTP daemon thread
        if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings", "smtpd"):
            smtpServerThread = smtpServer()
            smtpServerThread.start()

        # Start the thread that calculates POWs
        objectProcessorThread = objectProcessor()
        objectProcessorThread.daemon = False  # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
        objectProcessorThread.start()

        # Start the cleanerThread
        singleCleanerThread = singleCleaner()
        singleCleanerThread.daemon = True  # close the main program even if there are threads left
        singleCleanerThread.start()

        shared.reloadMyAddressHashes()
        shared.reloadBroadcastSendersForWhichImWatching()

        if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
            try:
                apiNotifyPath = BMConfigParser().get(
                    'bitmessagesettings', 'apinotifypath')
            except:
                apiNotifyPath = ''
            if apiNotifyPath != '':
                with shared.printLock:
                    print('Trying to call', apiNotifyPath)

                call([apiNotifyPath, "startingUp"])
            singleAPIThread = singleAPI()
            singleAPIThread.daemon = True  # close the main program even if there are threads left
            singleAPIThread.start()

        BMConnectionPool()
        asyncoreThread = BMNetworkThread()
        asyncoreThread.daemon = True
        asyncoreThread.start()
        for i in range(BMConfigParser().getint("threads", "receive")):
            receiveQueueThread = ReceiveQueueThread(i)
            receiveQueueThread.daemon = True
            receiveQueueThread.start()
        announceThread = AnnounceThread()
        announceThread.daemon = True
        announceThread.start()
        state.invThread = InvThread()
        state.invThread.daemon = True
        state.invThread.start()
        state.addrThread = AddrThread()
        state.addrThread.daemon = True
        state.addrThread.start()
        state.downloadThread = DownloadThread()
        state.downloadThread.daemon = True
        state.downloadThread.start()

        connectToStream(1)

        if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'):
            import upnp
            upnpThread = upnp.uPnPThread()
            upnpThread.start()

        if daemon == False and BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon') == False:
            if state.curses == False:
                if not depends.check_pyqt():
                    print('PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download   or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
                    print('You can also run PyBitmessage with the new curses interface by providing \'-c\' as a commandline argument.')
                    sys.exit()

                import bitmessageqt
                bitmessageqt.run()
            else:
                if True:
#                if depends.check_curses():
                    print('Running with curses')
                    import bitmessagecurses
                    bitmessagecurses.runwrapper()
        else:
            BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')

        if daemon:
            while state.shutdown == 0:
                sleep(1)