コード例 #1
0
    def test_is_new_version_checker_enabled(self, include_prerelease, enabled, interval):
        with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                   new_callable=PropertyMock) as new_version_check_interval_mock:
            new_version_check_interval_mock.return_value = interval

            settings_manager = SettingsManager()
            get_is_new_version_checker_enabled_mock = Mock(return_value=enabled)
            get_new_version_check_include_prerelease_mock = Mock(return_value=include_prerelease)
            settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled_mock
            settings_manager.get_new_version_check_include_prerelease = get_new_version_check_include_prerelease_mock

            new_version_checker = NewVersionChecker(False)
            new_version_checker.execute = Mock()

            settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker)

            body = self.simulate_request("/api/settings/new_version_checker", decode='utf-8')

            self.assertEqual(self.srmock.status, falcon.HTTP_OK)
            self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type'])

            result = json.loads(body)

            expected = {'include_prerelease': include_prerelease, 'enabled': enabled, 'interval': interval}
            self.assertEqual(result, expected)

            get_is_new_version_checker_enabled_mock.assert_called_once_with()
            get_new_version_check_include_prerelease_mock.assert_called_once_with()
            new_version_check_interval_mock.assert_called_once_with()
コード例 #2
0
    def test_patch_test(self, patch_include_prerelease, patch_enabled, patch_interval, update_include_prerelease, update_enabled, update_interval):
        with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                   new_callable=PropertyMock) as new_version_check_interval_mock:

            new_version_check_interval_mock.return_value = 4000

            settings_manager = SettingsManager()
            settings_manager.get_new_version_check_include_prerelease = Mock(return_value=False)
            settings_manager.set_new_version_check_include_prerelease = Mock()
            settings_manager.get_is_new_version_checker_enabled = Mock(return_value=True)
            settings_manager.set_is_new_version_checker_enabled = Mock()
            settings_manager.new_version_check_interval = PropertyMock(return_value=3600)

            new_version_checker = NewVersionChecker(False)
            update_mock = Mock()
            new_version_checker.update = update_mock

            settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker)

            request = dict()
            if patch_include_prerelease is not None:
                request['include_prerelease'] = patch_include_prerelease
            if patch_enabled is not None:
                request['enabled'] = patch_enabled
            if patch_interval is not None:
                request['interval'] = patch_interval
            self.simulate_request('/api/settings/new_version_checker', method="PATCH", body=json.dumps(request))

            self.assertEqual(self.srmock.status, falcon.HTTP_NO_CONTENT)

            update_mock.assert_called_once_with(update_include_prerelease, update_enabled, update_interval)
コード例 #3
0
    def test_new_public_version_url(self, version):
        checker = NewVersionChecker(False)

        with patch('monitorrent.new_version_checker.monitorrent', create=True) as version_mock:
            version_mock.__version__ = version

            checker.execute()

            self.assertEqual('https://github.com/werwolfby/monitorrent/releases/tag/1.0.2', checker.new_version_url)
コード例 #4
0
    def test_get_latest_release_with_error_tag_success(self, mocker):
        """
        :type mocker: Mocker
        """
        checker = NewVersionChecker(Mock(), True)

        mocker.get(
            'https://api.github.com/repos/werwolfby/monitorrent/releases',
            text=self.read_httpretty_content('github.com_releases.json',
                                             encoding='utf-8'))
        self.assertEqual('1.1.0-rc.4', checker.get_latest_release())
コード例 #5
0
    def test_update(self, include_prerelease, is_started, start_interval,
                    enabled, interval, start_called, stop_called):
        checker = NewVersionChecker(Mock(), False)

        def start_side_effect(i):
            checker.interval = i

        start_mock = Mock(side_effect=start_side_effect)
        stop_mock = Mock()
        is_started_mock = Mock(return_value=is_started)

        checker.interval = start_interval
        checker.start = start_mock
        checker.stop = stop_mock
        checker.is_started = is_started_mock

        checker.update(include_prerelease, enabled, interval)

        self.assertEqual(checker.interval, interval)
        self.assertEqual(checker.include_prereleases, include_prerelease)
        if start_called:
            start_mock.assert_called_once_with(interval)
        else:
            start_mock.assert_not_called()

        if stop_called:
            stop_mock.assert_called_once()
        else:
            stop_mock.assert_not_called()
コード例 #6
0
    def test_get_url(self, url):
        new_version_checker = NewVersionChecker(False)
        new_version_resource = NewVersion(new_version_checker)
        new_version_checker.new_version_url = url
        self.api.add_route('/api/new_version', new_version_resource)

        body = self.simulate_request("/api/new_version", decode='utf-8')

        self.assertEqual(self.srmock.status, falcon.HTTP_OK)
        self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type'])

        result = json.loads(body)

        self.assertEqual(result, {'url': url})
コード例 #7
0
    def test_get_url(self, url):
        new_version_checker = NewVersionChecker(Mock(), False)
        new_version_resource = NewVersion(new_version_checker)
        new_version_checker.new_version_url = url
        self.api.add_route('/api/new_version', new_version_resource)

        body = self.simulate_request("/api/new_version", decode='utf-8')

        self.assertEqual(self.srmock.status, falcon.HTTP_OK)
        self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type'])

        result = json.loads(body)

        self.assertEqual(result, {'url': url})
コード例 #8
0
    def test_start_twice_should_raise(self):
        checker = NewVersionChecker(Mock(), False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(10)
        with self.assertRaises(Exception):
            checker.start(10)
        checker.stop()

        execute_mock.assert_not_called()
コード例 #9
0
    def test_is_started(self):
        checker = NewVersionChecker(Mock(), False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(10)
        self.assertTrue(checker.is_started())
        checker.stop()
        self.assertFalse(checker.is_started())

        execute_mock.assert_not_called()
コード例 #10
0
    def test_update(self, include_prerelease, is_started, start_interval, enabled, interval, start_called, stop_called):
        checker = NewVersionChecker(False)

        def start_side_effect(i):
            checker.interval = i

        start_mock = Mock(side_effect=start_side_effect)
        stop_mock = Mock()
        is_started_mock = Mock(return_value=is_started)

        checker.interval = start_interval
        checker.start = start_mock
        checker.stop = stop_mock
        checker.is_started = is_started_mock

        checker.update(include_prerelease, enabled, interval)

        self.assertEqual(checker.interval, interval)
        self.assertEqual(checker.include_prereleases, include_prerelease)
        if start_called:
            start_mock.assert_called_once_with(interval)
        else:
            start_mock.assert_not_called()

        if stop_called:
            stop_mock.assert_called_once()
        else:
            stop_mock.assert_not_called()
コード例 #11
0
    def test_bad_request(self, body):
        with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                   new_callable=PropertyMock) as new_version_check_interval_mock:
            new_version_check_interval_mock.return_value = 4000

            settings_manager = SettingsManager()
            get_is_new_version_checker_enabled = Mock()
            settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled

            new_version_checker = NewVersionChecker(False)
            new_version_checker.execute = Mock()

            settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker)

            self.simulate_request("/api/settings/new_version_checker", method="PATCH", body=json.dumps(body) if body else None)

            self.assertEqual(self.srmock.status, falcon.HTTP_BAD_REQUEST)
コード例 #12
0
    def test_patch_test(self, patch_include_prerelease, patch_enabled,
                        patch_interval, update_include_prerelease,
                        update_enabled, update_interval):
        with patch(
                'monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                new_callable=PropertyMock) as new_version_check_interval_mock:

            new_version_check_interval_mock.return_value = 4000

            settings_manager = SettingsManager()
            settings_manager.get_new_version_check_include_prerelease = Mock(
                return_value=False)
            settings_manager.set_new_version_check_include_prerelease = Mock()
            settings_manager.get_is_new_version_checker_enabled = Mock(
                return_value=True)
            settings_manager.set_is_new_version_checker_enabled = Mock()
            settings_manager.new_version_check_interval = PropertyMock(
                return_value=3600)

            new_version_checker = NewVersionChecker(Mock(), False)
            update_mock = Mock()
            new_version_checker.update = update_mock

            settings_new_version_checker = SettingsNewVersionChecker(
                settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker',
                               settings_new_version_checker)

            request = dict()
            if patch_include_prerelease is not None:
                request['include_prerelease'] = patch_include_prerelease
            if patch_enabled is not None:
                request['enabled'] = patch_enabled
            if patch_interval is not None:
                request['interval'] = patch_interval
            self.simulate_request('/api/settings/new_version_checker',
                                  method="PATCH",
                                  body=json.dumps(request))

            self.assertEqual(self.srmock.status, falcon.HTTP_NO_CONTENT)

            update_mock.assert_called_once_with(update_include_prerelease,
                                                update_enabled,
                                                update_interval)
コード例 #13
0
    def test_is_started(self):
        checker = NewVersionChecker(False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(10)
        self.assertTrue(checker.is_started())
        checker.stop()
        self.assertFalse(checker.is_started())

        execute_mock.assert_not_called()
コード例 #14
0
    def test_is_new_version_checker_enabled(self, include_prerelease, enabled,
                                            interval):
        with patch(
                'monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                new_callable=PropertyMock) as new_version_check_interval_mock:
            new_version_check_interval_mock.return_value = interval

            settings_manager = SettingsManager()
            get_is_new_version_checker_enabled_mock = Mock(
                return_value=enabled)
            get_new_version_check_include_prerelease_mock = Mock(
                return_value=include_prerelease)
            settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled_mock
            settings_manager.get_new_version_check_include_prerelease = get_new_version_check_include_prerelease_mock

            new_version_checker = NewVersionChecker(Mock(), False)
            new_version_checker.execute = Mock()

            settings_new_version_checker = SettingsNewVersionChecker(
                settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker',
                               settings_new_version_checker)

            body = self.simulate_request("/api/settings/new_version_checker",
                                         decode='utf-8')

            self.assertEqual(self.srmock.status, falcon.HTTP_OK)
            self.assertTrue(
                'application/json' in self.srmock.headers_dict['Content-Type'])

            result = json.loads(body)

            expected = {
                'include_prerelease': include_prerelease,
                'enabled': enabled,
                'interval': interval
            }
            self.assertEqual(result, expected)

            get_is_new_version_checker_enabled_mock.assert_called_once_with()
            get_new_version_check_include_prerelease_mock.assert_called_once_with(
            )
            new_version_check_interval_mock.assert_called_once_with()
コード例 #15
0
    def test_start_twice_should_raise(self):
        checker = NewVersionChecker(False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(10)
        with self.assertRaises(Exception):
            checker.start(10)
        checker.stop()

        execute_mock.assert_not_called()
コード例 #16
0
    def test_new_public_version_url(self, version):
        notifier_manager_execute = MagicMock()
        notifier_manager_execute.notify = Mock()
        notifier_manager_execute.__enter__ = Mock(
            return_value=notifier_manager_execute)

        notifier_manager = Mock()
        notifier_manager.execute = Mock(name="notifier_manager.execute123",
                                        return_value=notifier_manager_execute)
        checker = NewVersionChecker(notifier_manager, False)

        with patch('monitorrent.new_version_checker.monitorrent',
                   create=True) as version_mock:
            version_mock.__version__ = version

            checker.execute()

            self.assertEqual(
                'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2',
                checker.new_version_url)
            notifier_manager_execute.notify.assert_called_once()
コード例 #17
0
    def test_new_public_version_notify_second_time_after_version_change(
            self, mocker):
        notifier_manager_execute = MagicMock()
        notifier_manager_execute.notify = Mock()
        notifier_manager_execute.__enter__ = Mock(
            return_value=notifier_manager_execute)

        notifier_manager = Mock()
        notifier_manager.execute = Mock(name="notifier_manager.execute123",
                                        return_value=notifier_manager_execute)
        # noinspection PyTypeChecker
        checker = NewVersionChecker(notifier_manager, False)

        with patch('monitorrent.new_version_checker.monitorrent',
                   create=True) as version_mock:
            version_mock.__version__ = "1.0.0"

            mocker.get(
                'https://api.github.com/repos/werwolfby/monitorrent/releases',
                text=self.read_httpretty_content('github.com_releases.json',
                                                 encoding='utf-8'))
            checker.execute()

            assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2' == checker.new_version_url
            notifier_manager_execute.notify.assert_called_once()
            notify_message = notifier_manager_execute.notify.mock_calls[0][1][
                0]
            assert "1.0.2" in notify_message
            assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2' in notify_message

            checker.execute()

            notifier_manager_execute.notify.assert_called_once()
            notifier_manager_execute.notify.reset_mock()

            mocker.get(
                'https://api.github.com/repos/werwolfby/monitorrent/releases',
                text=self.read_httpretty_content('github.com_releases_2.json',
                                                 encoding='utf-8'))
            checker.execute()

            self.assertEqual(
                'https://github.com/werwolfby/monitorrent/releases/tag/1.1.1',
                checker.new_version_url)

            notifier_manager_execute.notify.assert_called_once()
            notify_message = notifier_manager_execute.notify.mock_calls[0][1][
                0]
            assert "1.1.1" in notify_message
            assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.1.1' in notify_message
コード例 #18
0
    def test_timer_stop_dont_call_execute(self):
        checker = NewVersionChecker(Mock(), False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(1)
        checker.stop()

        execute_mock.assert_not_called()

        self.assertLess(execute_mock.call_count, 4)
コード例 #19
0
    def test_bad_request(self, body):
        with patch(
                'monitorrent.settings_manager.SettingsManager.new_version_check_interval',
                new_callable=PropertyMock) as new_version_check_interval_mock:
            new_version_check_interval_mock.return_value = 4000

            settings_manager = SettingsManager()
            get_is_new_version_checker_enabled = Mock()
            settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled

            new_version_checker = NewVersionChecker(Mock(), False)
            new_version_checker.execute = Mock()

            settings_new_version_checker = SettingsNewVersionChecker(
                settings_manager, new_version_checker)
            self.api.add_route('/api/settings/new_version_checker',
                               settings_new_version_checker)

            self.simulate_request("/api/settings/new_version_checker",
                                  method="PATCH",
                                  body=json.dumps(body) if body else None)

            self.assertEqual(self.srmock.status, falcon.HTTP_BAD_REQUEST)
コード例 #20
0
    def test_timer_stop_dont_call_execute(self):
        checker = NewVersionChecker(False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(1)
        checker.stop()

        execute_mock.assert_not_called()

        self.assertLess(execute_mock.call_count, 4)
コード例 #21
0
    def test_timer_calls(self):
        checker = NewVersionChecker(Mock(), False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(0.1)
        sleep(0.3)
        checker.stop()

        self.assertGreaterEqual(execute_mock.call_count, 2)
        self.assertLess(execute_mock.call_count, 4)

        sleep(0.3)

        self.assertLess(execute_mock.call_count, 4)
コード例 #22
0
    def test_timer_calls(self):
        checker = NewVersionChecker(False)

        execute_mock = Mock(return_value=True)
        checker.execute = execute_mock

        checker.start(0.1)
        sleep(0.3)
        checker.stop()

        self.assertGreaterEqual(execute_mock.call_count, 2)
        self.assertLess(execute_mock.call_count, 4)

        sleep(0.3)

        self.assertLess(execute_mock.call_count, 4)
コード例 #23
0
    def test_get_latest_public_release(self):
        checker = NewVersionChecker(Mock(), False)

        self.assertEqual('1.0.2', checker.get_latest_release())
コード例 #24
0
    def test_get_latest_prerelease_release(self):
        checker = NewVersionChecker(Mock(), True)

        self.assertEqual('1.1.0-rc.1.1', checker.get_latest_release())
コード例 #25
0
    def test_get_latest_prerelease_release(self):
        checker = NewVersionChecker(True)

        self.assertEqual('1.1.0-rc.1.1', checker.get_latest_release())
コード例 #26
0
    def test_get_latest_public_release(self):
        checker = NewVersionChecker(False)

        self.assertEqual('1.0.2', checker.get_latest_release())
コード例 #27
0
def main():
    def try_int(s, base=10, val=None):
        if s is None:
            return None
        try:
            return int(s, base)
        except ValueError:
            return val

    class Config(object):
        debug = False
        ip = '0.0.0.0'
        port = 6687
        db_path = 'monitorrent.db'
        config = 'config.py'

        def __init__(self, parsed_args):
            if parsed_args.config is not None and not os.path.isfile(parsed_args.config):
                warnings.warn('File not found: {}'.format(parsed_args.config))
            config_path = parsed_args.config or self.config
            if os.path.isfile(config_path):
                # noinspection PyBroadException
                try:
                    parsed_config = {}
                    with open(config_path) as config_file:
                        six.exec_(compile(config_file.read(), config_path, 'exec'), {}, parsed_config)
                    self.debug = parsed_config.get('debug', self.debug)
                    self.ip = parsed_config.get('ip', self.ip)
                    self.port = parsed_config.get('port', self.port)
                    self.db_path = parsed_config.get('db_path', self.db_path)
                except:
                    ex, val, tb = sys.exc_info()
                    warnings.warn('Error reading: {0}: {1} ({2}'.format(parsed_args.config, ex, val))

            env_debug = (os.environ.get('MONITORRENT_DEBUG', None) in ['true', 'True', '1'])

            self.debug = parsed_args.debug or env_debug or self.debug
            self.ip = parsed_args.ip or os.environ.get('MONITORRENT_IP', None) or self.ip
            self.port = parsed_args.port or try_int(os.environ.get('MONITORRENT_PORT', None)) or self.port
            self.db_path = parsed_args.db_path or os.environ.get('MONITORRENT_DB_PATH', None) or self.db_path

    parser = argparse.ArgumentParser(description='Monitorrent server')
    parser.add_argument('--debug', action='store_true',
                        help='Run in debug mode. Secret key is always the same.')
    parser.add_argument('--ip', type=str, dest='ip',
                        help='Bind interface. Default is {0}'.format(Config.ip))
    parser.add_argument('--port', type=int, dest='port',
                        help='Port for server. Default is {0}'.format(Config.port))
    parser.add_argument('--db-path', type=str, dest='db_path',
                        help='Path to SQL lite database. Default is to {0}'.format(Config.db_path))
    parser.add_argument('--config', type=str, dest='config',
                        default=os.environ.get('MONITORRENT_CONFIG', None),
                        help='Path to config file (default {0})'.format(Config.config))

    parsed_args = parser.parse_args()
    config = Config(parsed_args)

    db_connection_string = "sqlite:///" + config.db_path

    init_db_engine(db_connection_string, False)
    load_plugins()
    upgrade()
    create_db()

    settings_manager = SettingsManager()
    tracker_manager = TrackersManager(settings_manager, get_plugins('tracker'))
    clients_manager = DbClientsManager(settings_manager, get_plugins('client'))
    notifier_manager = NotifierManager(settings_manager, get_plugins('notifier'))

    log_manager = ExecuteLogManager()
    engine_runner_logger = DbLoggerWrapper(log_manager, settings_manager)
    engine_runner = DBEngineRunner(engine_runner_logger, settings_manager, tracker_manager,
                                   clients_manager, notifier_manager)

    include_prerelease = settings_manager.get_new_version_check_include_prerelease()
    new_version_checker = NewVersionChecker(notifier_manager, include_prerelease)
    if settings_manager.get_is_new_version_checker_enabled():
        # noinspection PyBroadException
        try:
            new_version_checker.execute()
        except:
            pass
        new_version_checker.start(settings_manager.new_version_check_interval)

    debug = config.debug

    if debug:
        secret_key = 'Secret!'
        token = 'monitorrent'
    else:
        secret_key = os.urandom(24)
        token = ''.join(random.choice(string.ascii_letters) for _ in range(8))

    app = create_app(secret_key, token, tracker_manager, clients_manager, notifier_manager, settings_manager,
                     engine_runner, log_manager, new_version_checker)
    server_start_params = (config.ip, config.port)
    server = wsgi.Server(server_start_params, app)
    print('Server started on {0}:{1}'.format(*server_start_params))

    try:
        server.start()
    except KeyboardInterrupt:
        engine_runner.stop()
        server.stop()
コード例 #28
0
ファイル: server.py プロジェクト: werwolfby/monitorrent
def main():
    def try_int(s, base=10, val=None):
        if s is None:
            return None
        try:
            return int(s, base)
        except ValueError:
            return val

    class Config(object):
        debug = False
        ip = '0.0.0.0'
        port = 6687
        db_path = 'monitorrent.db'
        config = 'config.py'

        def __init__(self, parsed_args):
            if parsed_args.config is not None and not os.path.isfile(parsed_args.config):
                warnings.warn('File not found: {}'.format(parsed_args.config))
            config_path = parsed_args.config or self.config
            if os.path.isfile(config_path):
                # noinspection PyBroadException
                try:
                    parsed_config = {}
                    with open(config_path) as config_file:
                        six.exec_(compile(config_file.read(), config_path, 'exec'), {}, parsed_config)
                    self.debug = parsed_config.get('debug', self.debug)
                    self.ip = parsed_config.get('ip', self.ip)
                    self.port = parsed_config.get('port', self.port)
                    self.db_path = parsed_config.get('db_path', self.db_path)
                except:
                    ex, val, tb = sys.exc_info()
                    warnings.warn('Error reading: {0}: {1} ({2}'.format(parsed_args.config, ex, val))

            env_debug = (os.environ.get('MONITORRENT_DEBUG', None) in ['true', 'True', '1'])

            self.debug = parsed_args.debug or env_debug or self.debug
            self.ip = parsed_args.ip or os.environ.get('MONITORRENT_IP', None) or self.ip
            self.port = parsed_args.port or try_int(os.environ.get('MONITORRENT_PORT', None)) or self.port
            self.db_path = parsed_args.db_path or os.environ.get('MONITORRENT_DB_PATH', None) or self.db_path

    parser = argparse.ArgumentParser(description='Monitorrent server')
    parser.add_argument('--debug', action='store_true',
                        help='Run in debug mode. Secret key is always the same.')
    parser.add_argument('--ip', type=str, dest='ip',
                        help='Bind interface. Default is {0}'.format(Config.ip))
    parser.add_argument('--port', type=int, dest='port',
                        help='Port for server. Default is {0}'.format(Config.port))
    parser.add_argument('--db-path', type=str, dest='db_path',
                        help='Path to SQL lite database. Default is to {0}'.format(Config.db_path))
    parser.add_argument('--config', type=str, dest='config',
                        default=os.environ.get('MONITORRENT_CONFIG', None),
                        help='Path to config file (default {0})'.format(Config.config))

    parsed_args = parser.parse_args()
    config = Config(parsed_args)

    db_connection_string = "sqlite:///" + config.db_path

    init_db_engine(db_connection_string, False)
    load_plugins()
    upgrade()
    create_db()

    settings_manager = SettingsManager()
    tracker_manager = TrackersManager(settings_manager, get_plugins('tracker'))
    clients_manager = DbClientsManager(get_plugins('client'), settings_manager)
    notifier_manager = NotifierManager(get_plugins('notifier'))

    log_manager = ExecuteLogManager()
    engine_runner_logger = DbLoggerWrapper(None, log_manager, settings_manager)
    engine_runner = DBEngineRunner(engine_runner_logger, tracker_manager, clients_manager)

    new_version_checker = NewVersionChecker(settings_manager.get_new_version_check_include_prerelease())
    if settings_manager.get_is_new_version_checker_enabled():
        # noinspection PyBroadException
        try:
            new_version_checker.execute()
        except:
            pass
        new_version_checker.start(settings_manager.new_version_check_interval)

    debug = config.debug

    if debug:
        secret_key = 'Secret!'
        token = 'monitorrent'
    else:
        secret_key = os.urandom(24)
        token = ''.join(random.choice(string.ascii_letters) for _ in range(8))

    app = create_app(secret_key, token, tracker_manager, clients_manager, notifier_manager, settings_manager,
                     engine_runner, log_manager, new_version_checker)
    d = wsgiserver.WSGIPathInfoDispatcher({'/': app})
    server_start_params = (config.ip, config.port)
    server = wsgiserver.CherryPyWSGIServer(server_start_params, d)
    print('Server started on {0}:{1}'.format(*server_start_params))

    try:
        server.start()
    except KeyboardInterrupt:
        engine_runner.stop()
        server.stop()